~t7-vla7-lz/psiphon/psiphon

« back to all changes in this revision

Viewing changes to trunk/testing/selenium_scripts/selenium/doctool/doc2html.xml

  • Committer: Eugene Fryntov
  • Date: 2016-11-15 22:13:59 UTC
  • mfrom: (373.1.1 psiphon)
  • Revision ID: e.fryntov@psiphon.ca-20161115221359-f6s56ue1a54n4ijj
merged lp:~t7-vla7-lz/psiphon/psiphon @ 374

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?xml version="1.0" encoding="UTF-8"?>
2
 
<!DOCTYPE xslt [
3
 
  <!--Used to control code intenting -->
4
 
  <!ENTITY nbsp "&#xa0;">
5
 
]>
6
 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
7
 
 
8
 
<xsl:strip-space elements="*"/><xsl:output method="html"/>
9
 
 
10
 
<!-- TOP LEVEL -->
11
 
<xsl:template match="/">
12
 
    <html><head><title>Selenium Reference</title></head><body>
13
 
        <xsl:call-template name="header" />
14
 
        <xsl:apply-templates select="//top" />
15
 
        <a name="actions"></a><h2>Selenium Actions</h2>
16
 
        <dl>
17
 
                <xsl:apply-templates select="//function[not(return) and not(starts-with(@name, 'assert'))]" mode="action">
18
 
                    <xsl:sort select="@name" />
19
 
                </xsl:apply-templates>
20
 
        </dl>
21
 
        <a name="accessors"></a><h2>Selenium Accessors</h2>
22
 
        <dl>
23
 
                <xsl:apply-templates select="//function[starts-with(@name, 'assert')]" mode="assertion">
24
 
                    <xsl:sort select="@name" />
25
 
                </xsl:apply-templates>
26
 
                <xsl:apply-templates select="//function[return]" mode="accessor">
27
 
                    <xsl:sort select="@name" />
28
 
                </xsl:apply-templates>
29
 
        </dl>
30
 
        <xsl:call-template name="footer" />
31
 
        </body></html>
32
 
</xsl:template>
33
 
 
34
 
<xsl:template name="header">
35
 
        <h1>Selenium Reference</h1>
36
 
        <ol>
37
 
        <li><a href="#name">Concepts</a></li>
38
 
        <ol>
39
 
        <li><a href="#locators">Element Locators</a></li>
40
 
        <li><a href="#element-filters">Element Filters</a></li>
41
 
        <li><a href="#patterns">String-match Patterns</a></li>
42
 
        </ol>
43
 
        <li><a href="#actions">Selenium Actions</a></li>
44
 
        <li><a href="#accessors">Selenium Accessors</a></li>
45
 
        <li><a href="#parameter-construction-and-variables">Parameter Construction and Variables</a></li>
46
 
        <li><a href="#whitespace">Whitespace Rules</a></li>
47
 
        <li><a href="#extending-selenium">Extending Selenium</a></li>
48
 
        </ol>
49
 
        
50
 
        <h2>Concepts</h2><a name="concepts"></a>
51
 
        <p>A <strong>command</strong> is what tells Selenium what to do. Selenium commands come in three 'flavors': <strong>Actions</strong>, <strong>Accessors</strong> and <strong>Assertions</strong>.
52
 
        Each command call is one line in the test table of the form:</p>
53
 
        <blockquote>
54
 
        <table border="1" class="table">
55
 
        <colgroup>
56
 
        <col width="39%" />
57
 
        <col width="33%" />
58
 
        <col width="28%" />
59
 
        </colgroup>
60
 
        <tbody valign="top">
61
 
        <tr><td>command</td>
62
 
        <td>target</td>
63
 
        <td>value</td>
64
 
        </tr>
65
 
        </tbody>
66
 
        </table>
67
 
        </blockquote>
68
 
        <p><strong>Actions</strong> are commands that generally manipulate the state of the application. They do things like &quot;click this link&quot; and &quot;select that option&quot;. If an Action fails, or has an error, the execution of the current test is stopped.</p>
69
 
        <p>Many Actions can be called with the &quot;AndWait&quot; suffix, e.g. "clickAndWait".
70
 
        This suffix tells Selenium that the action will cause the browser to make a call to the server,
71
 
        and that Selenium should wait for a new page to load.</p>
72
 
        
73
 
        <p><strong>Accessors</strong> examine the state of the application and store the results in variables, e.g. "storeTitle".  They are also used to automatically generate Assertions.</p>
74
 
        <p><strong>Assertions</strong> are like Accessors, but they verify that the state of the application conforms to what is expected. Examples include &quot;make sure the page title is X&quot; and &quot;verify that this checkbox is checked&quot;.</p>
75
 
        
76
 
        <p>All Selenium Assertions can be used in 3 modes: &quot;assert&quot;, &quot;verify&quot;, and "waitFor". For example, you can "assertText", "verifyText" and "waitForText".  When an &quot;assert&quot; fails, the test is aborted. When a &quot;verify&quot; fails, the test will continue execution, logging the failure.  This allows a single &quot;assert&quot; to ensure that the application is on the correct page, followed by a bunch of &quot;verify&quot; assertions to test form field values, labels, etc.</p>
77
 
        
78
 
        <p>&quot;waitFor&quot; commands wait for some condition to become true (which can be useful for testing Ajax applications).
79
 
        They will succeed immediately if the condition is already true.
80
 
        However, they will fail and halt the test if the condition does not become true within the current timeout setting
81
 
        (see the <strong>setTimeout</strong> action below).
82
 
        </p>
83
 
        <p><strong>Element Locators</strong> tell Selenium which HTML element a command refers to. Many commands require an Element Locator as the &quot;target&quot; attribute. Examples of Element Locators include &quot;elementId&quot; and &quot;document.forms[0].element&quot;. These are described more clearly in the next section.</p>
84
 
        <p><strong>Patterns</strong> are used for various reasons, e.g. to specify the expected value of an input field, or identify a select option.  Selenium supports various types of pattern, including regular-expressions, all of which are described in more detail below.</p>
85
 
        
86
 
        
87
 
</xsl:template>
88
 
 
89
 
<xsl:template name="footer">
90
 
        <h2><a name="parameter-construction-and-variables">Parameter construction and Variables</a></h2>
91
 
        <blockquote>
92
 
        <p>All Selenium command parameters can be constructed using both simple
93
 
        variable substitution as well as full javascript. Both of these
94
 
        mechanisms can access previously stored variables, but do so using
95
 
        different syntax.</p>
96
 
        <p><a name="storedVars"></a><strong>Stored Variables</strong></p>
97
 
        <p>The commands <em>store</em>, <em>storeValue</em> and <em>storeText</em> can be used to store a variable
98
 
        value for later access. Internally, these variables are stored in a map called &quot;storedVars&quot;,
99
 
        with values keyed by the variable name. These commands are documented in the command reference.</p>
100
 
        <p><strong>Variable substitution</strong></p>
101
 
        <p>Variable substitution provides a simple way to include a previously stored variable in a
102
 
        command parameter. This is a simple mechanism, by which the variable to substitute is indicated
103
 
        by ${variableName}. Multiple variables can be substituted, and intermixed with static text.</p>
104
 
        <p>Example:</p>
105
 
        <blockquote>
106
 
        <table border="1" class="table">
107
 
        <colgroup>
108
 
        <col width="18%" />
109
 
        <col width="36%" />
110
 
        <col width="45%" />
111
 
        </colgroup>
112
 
        <tbody valign="top">
113
 
        <tr><td>store</td>
114
 
        <td>Mr</td>
115
 
        <td>title</td>
116
 
        </tr>
117
 
        <tr><td>storeValue</td>
118
 
        <td>nameField</td>
119
 
        <td>surname</td>
120
 
        </tr>
121
 
        <tr><td>store</td>
122
 
        <td>${title} ${surname}</td>
123
 
        <td>fullname</td>
124
 
        </tr>
125
 
        <tr><td>type</td>
126
 
        <td>textElement</td>
127
 
        <td>Full name is: ${fullname}</td>
128
 
        </tr>
129
 
        </tbody>
130
 
        </table>
131
 
        </blockquote>
132
 
        <p><strong>Javascript evaluation</strong></p>
133
 
        <p>Javascript evaluation provides the full power of javascript in constructing a command parameter.
134
 
        To use this mechanism, the <em>entire</em> parameter value must be prefixed by
135
 
        'javascript{' with a trailing '}'. The text inside the braces is evaluated as a javascript expression,
136
 
        and can access previously stored variables using the <em>storedVars</em> map detailed above.
137
 
        Note that variable substitution cannot be combined with javascript evaluation.</p>
138
 
        <p>Example:</p>
139
 
        <blockquote>
140
 
        <table border="1" class="table">
141
 
        <colgroup>
142
 
        <col width="9%" />
143
 
        <col width="44%" />
144
 
        <col width="46%" />
145
 
        </colgroup>
146
 
        <tbody valign="top">
147
 
        <tr><td>store</td>
148
 
        <td>javascript{'merchant' + (new Date()).getTime()}</td>
149
 
        <td>merchantId</td>
150
 
        </tr>
151
 
        <tr><td>type</td>
152
 
        <td>textElement</td>
153
 
        <td>javascript{storedVars['merchantId'].toUpperCase()}</td>
154
 
        </tr>
155
 
        </tbody>
156
 
        </table>
157
 
        </blockquote>
158
 
        </blockquote>
159
 
        
160
 
        <div class="section" id="whitespace">
161
 
        <h2><a name="whitespace">Whitespace Rules</a></h2>
162
 
        <blockquote>
163
 
        <p>HTML automatically normalizes whitespace within elements, ignoring leading/trailing spaces and converting extra spaces, tabs and newlines into a single space.  When Selenium reads text out of the page, it attempts to duplicate this behavior, so you can ignore all the tabs and newlines in your HTML and do assertions based on how the text looks in the browser when rendered.  We do this by replacing all non-visible whitespace (including the non-breaking space "&amp;nbsp;") with a single space.  All visible newlines (&lt;br&gt;, &lt;p&gt;, and &lt;pre&gt;formatted newlines) should be preserved.</p>
164
 
        <p>We use the same normalization logic on the text of HTML Selenese test case tables.  This has a number of advantages.  First, you don't need to look at the HTML source of the page to figure out what your assertions should be; "&amp;nbsp;" symbols are invisible to the end user, and so you shouldn't have to worry about them when writing Selenese tests.  (You don't need to put "&amp;nbsp;" markers in your test case to assertText on a field that contains "&amp;nbsp;".)  You may also put extra newlines and spaces in your Selenese &lt;td&gt; tags; since we use the same normalization logic on the test case as we do on the text, we can ensure that assertions and the extracted text will match exactly.</p>
165
 
        <p>This creates a bit of a problem on those rare occasions when you really want/need to insert extra whitespace in your test case.  For example, you may need to type text in a field like this: "foo&nbsp;&nbsp;&nbsp;".  But if you simply write &lt;td&gt;foo&nbsp;&nbsp;&nbsp;&lt;/td&gt; in your Selenese test case, we'll replace your extra spaces with just one space.</p>
166
 
        <p>This problem has a simple workaround.  We've defined a variable in Selenese, ${space}, whose value is a single space.  You can use ${space} to insert a space that won't be automatically trimmed, like this: &lt;td&gt;foo${space}${space}${space}&lt;/td&gt;.  We've also included a variable ${nbsp}, that you can use to insert a non-breaking space.</p>
167
 
        <p>Note that XPaths do <i>not</i> normalize whitespace the way we do.  If you need to write an XPath like //div[text()="hello world"] but the HTML of the link is really "hello&amp;nbsp;world", you'll need to insert a real "&amp;nbsp;" into your Selenese test case to get it to match, like this: //div[text()="hello${nbsp}world"].</p>
168
 
        </blockquote>
169
 
        </div>
170
 
        
171
 
        <div class="section" id="extending-selenium">
172
 
        <h2><a name="extending-selenium">Extending Selenium</a></h2>
173
 
        <blockquote>
174
 
        <p>It can be quite simple to extend Selenium, adding your own actions, assertions and locator-strategies.
175
 
        This is done with javascript by adding methods to the Selenium object prototype, and the PageBot
176
 
        object prototype. On startup, Selenium will automatically look through methods on these prototypes,
177
 
        using name patterns to recognise which ones are actions, assertions and locators.</p>
178
 
        <p>The following examples try to give an indication of how Selenium can be extended with javascript.</p>
179
 
        </blockquote>
180
 
        <p><strong>Actions</strong></p>
181
 
        <blockquote>
182
 
        <p>All <em>doFoo</em> methods on the Selenium prototype are added as actions. For each action <em>foo</em> there
183
 
        is also an action <em>fooAndWait</em> registered. An action method can take up to 2 parameters, which
184
 
        will be passed the second and third column values in the test.</p>
185
 
        <p>Example: Add a &quot;typeRepeated&quot; action to Selenium, which types the text twice into a text box.</p>
186
 
        <pre class="literal-block">
187
 
        Selenium.prototype.doTypeRepeated = function(locator, text) {
188
 
            // All locator-strategies are automatically handled by &quot;findElement&quot;
189
 
            var element = this.page().findElement(locator);
190
 
        
191
 
            // Create the text to type
192
 
            var valueToType = text + text;
193
 
        
194
 
            // Replace the element text with the new text
195
 
            this.page().replaceText(element, valueToType);
196
 
        };
197
 
        </pre>
198
 
        </blockquote>
199
 
        <p><strong>Accessors/Assertions</strong></p>
200
 
        <blockquote>
201
 
        <p>All <em>getFoo</em> and <em>isFoo</em> methods on the Selenium prototype are added as accessors (storeFoo). For each accessor there
202
 
        is an <em>assertFoo</em>, <em>verifyFoo</em> and <em>waitForFoo</em> registered. An assert method can take up to 2 parameters, which
203
 
        will be passed the second and third column values in the test.  You can also define your own assertions literally
204
 
        as simple "assert" methods, which will also auto-generate "verify" and "waitFor" commands.</p>
205
 
        <p>Example: Add a <em>valueRepeated</em> assertion, that makes sure that the element value
206
 
        consists of the supplied text repeated. The 2 commands that would be available in tests would be
207
 
        <em>assertValueRepeated</em> and <em>verifyValueRepeated</em>.</p>
208
 
        <pre class="literal-block">
209
 
        Selenium.prototype.assertValueRepeated = function(locator, text) {
210
 
            // All locator-strategies are automatically handled by &quot;findElement&quot;
211
 
            var element = this.page().findElement(locator);
212
 
        
213
 
            // Create the text to verify
214
 
            var expectedValue = text + text;
215
 
        
216
 
            // Get the actual element value
217
 
            var actualValue = element.value;
218
 
        
219
 
            // Make sure the actual value matches the expected
220
 
            Assert.matches(expectedValue, actualValue);
221
 
        };
222
 
        </pre>
223
 
        </blockquote>
224
 
        <p><strong>Automatic availability of storeFoo, assertFoo, assertNotFoo, waitForFoo and waitForNotFoo for every getFoo</strong></p>
225
 
        <blockquote>
226
 
        <p>All <em>getFoo</em> and <em>isFoo</em> methods on the Selenium prototype automatically result in the availability
227
 
        of storeFoo, assertFoo, assertNotFoo, verifyFoo, verifyNotFoo, waitForFoo, and waitForNotFoo commands.</p>
228
 
        <p>Example, if you add a getTextLength() method, the following commands will automatically be available:
229
 
        storeTextLength, assertTextLength, assertNotTextLength, verifyTextLength, verifyNotTextLength, waitForTextLength, and waitForNotTextLength commands.</p>
230
 
        <pre class="literal-block">
231
 
        Selenium.prototype.getTextLength = function(locator, text) {
232
 
            return this.getText(locator).length;
233
 
        };
234
 
        </pre>
235
 
        
236
 
        <p>Also note that the <em>assertValueRepeated</em> method described above could have been implemented using
237
 
        isValueRepeated, with the added benefit of also automatically getting assertNotValueRepeated, storeValueRepeated,
238
 
        waitForValueRepeated and waitForNotValueRepeated.</p>
239
 
        </blockquote>
240
 
        <p><strong>Locator Strategies</strong></p>
241
 
        <blockquote>
242
 
        <p>All <em>locateElementByFoo</em> methods on the PageBot prototype are added as locator-strategies. A locator strategy takes 2 parameters, the first being the locator string (minus the prefix), and the second being the document in which to search.</p>
243
 
        <p>Example: Add a &quot;valuerepeated=&quot; locator, that finds the first element a value attribute equal to the the supplied value repeated.</p>
244
 
        <pre class="literal-block">
245
 
        // The &quot;inDocument&quot; is a the document you are searching.
246
 
        PageBot.prototype.locateElementByValueRepeated = function(text, inDocument) {
247
 
            // Create the text to search for
248
 
            var expectedValue = text + text;
249
 
        
250
 
            // Loop through all elements, looking for ones that have 
251
 
            // a value === our expected value
252
 
            var allElements = inDocument.getElementsByTagName(&quot;*&quot;);
253
 
            for (var i = 0; i &lt; allElements.length; i++) {
254
 
                var testElement = allElements[i];
255
 
                if (testElement.value &amp;&amp; testElement.value === expectedValue) {
256
 
                    return testElement;
257
 
                }
258
 
            }
259
 
            return null;
260
 
        };
261
 
        </pre>
262
 
        </blockquote>
263
 
        <p><strong>user-extensions.js</strong></p>
264
 
        <blockquote>
265
 
        <p>By default, Selenium looks for a file called &quot;user-extensions.js&quot;, and loads the javascript code found in that file. This file provides a convenient location for adding features to Selenium, without needing to modify the core Selenium sources.</p>
266
 
        <p>In the standard distibution, this file does not exist. Users can create this file and place their extension code in this common location, removing the need to modify the Selenium sources, and hopefully assisting with the upgrade process.</p>
267
 
        </blockquote>
268
 
        </div>
269
 
</xsl:template>
270
 
 
271
 
<!-- Ignore the top comment in iedoc.xml; just process all of its children -->
272
 
<xsl:template match="top">
273
 
        <xsl:apply-templates />
274
 
</xsl:template>
275
 
 
276
 
<xsl:template match="comment">
277
 
        <xsl:apply-templates />
278
 
</xsl:template>
279
 
 
280
 
<!-- Print out assert* and all of its related assertions -->
281
 
<xsl:template match="function" mode="assertion">
282
 
        <dt><strong>
283
 
            <a>
284
 
                <xsl:attribute name="name">
285
 
                    <xsl:value-of select="@name" />
286
 
                </xsl:attribute>
287
 
            </a>
288
 
                <xsl:value-of select="@name" />
289
 
                (
290
 
                        <xsl:apply-templates select="param" mode="declaration-action"/>
291
 
                )
292
 
        </strong></dt>
293
 
        <dd>
294
 
                <xsl:apply-templates select="comment" />
295
 
                <p>Arguments:</p>
296
 
                <ul>
297
 
                        <xsl:apply-templates select="param" mode="comment" />
298
 
                </ul>
299
 
                <p>Related Assertions, automatically generated:</p>
300
 
                <ul>
301
 
                        <li> 
302
 
                                <xsl:call-template name="accessor-rename">
303
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
304
 
                                        <xsl:with-param name="prefix">assertNot</xsl:with-param>
305
 
                                </xsl:call-template>
306
 
                                (
307
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
308
 
                                        <xsl:if test="./return/@type != 'boolean'">
309
 
                                                <a href="#patterns">pattern</a>
310
 
                                        </xsl:if>
311
 
                                )
312
 
                        </li>
313
 
                        <li>
314
 
                                <xsl:call-template name="accessor-rename">
315
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
316
 
                                        <xsl:with-param name="prefix">verify</xsl:with-param>
317
 
                                </xsl:call-template>
318
 
                                (
319
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
320
 
                                        <xsl:if test="./return/@type != 'boolean'">
321
 
                                                <a href="#patterns">pattern</a>
322
 
                                        </xsl:if>
323
 
                                )
324
 
                        </li>
325
 
                        <li>
326
 
                                <xsl:call-template name="accessor-rename">
327
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
328
 
                                        <xsl:with-param name="prefix">verifyNot</xsl:with-param>
329
 
                                </xsl:call-template>
330
 
                                (
331
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
332
 
                                        <xsl:if test="./return/@type != 'boolean'">
333
 
                                                <a href="#patterns">pattern</a>
334
 
                                        </xsl:if>
335
 
                                )
336
 
                        </li>
337
 
                        <li>
338
 
                                <xsl:call-template name="accessor-rename">
339
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
340
 
                                        <xsl:with-param name="prefix">waitFor</xsl:with-param>
341
 
                                </xsl:call-template>
342
 
                                (
343
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
344
 
                                        <xsl:if test="./return/@type != 'boolean'">
345
 
                                                <a href="#patterns">pattern</a>
346
 
                                        </xsl:if>
347
 
                                )
348
 
                        </li>
349
 
                        <li>
350
 
                                <xsl:call-template name="accessor-rename">
351
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
352
 
                                        <xsl:with-param name="prefix">waitForNot</xsl:with-param>
353
 
                                </xsl:call-template>
354
 
                                (
355
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
356
 
                                        <xsl:if test="./return/@type != 'boolean'">
357
 
                                                <a href="#patterns">pattern</a>
358
 
                                        </xsl:if>
359
 
                                )
360
 
                        </li>
361
 
                </ul>
362
 
                        
363
 
        </dd>
364
 
        <br/>
365
 
</xsl:template>
366
 
 
367
 
<!-- Print out store* and all of its related assertions -->
368
 
<xsl:template match="function" mode="accessor">
369
 
    <dt><strong>
370
 
        <a>
371
 
                <xsl:attribute name="name">
372
 
                    <xsl:call-template name="accessor-rename">
373
 
                                <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
374
 
                                <xsl:with-param name="prefix">store</xsl:with-param>
375
 
                        </xsl:call-template>
376
 
                </xsl:attribute>
377
 
            </a>
378
 
                <xsl:call-template name="accessor-rename">
379
 
                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
380
 
                        <xsl:with-param name="prefix">store</xsl:with-param>
381
 
                </xsl:call-template>
382
 
                
383
 
                (
384
 
                        <xsl:apply-templates select="param" mode="declaration-accessor"/>
385
 
                        variableName
386
 
                )
387
 
                
388
 
        </strong></dt>
389
 
        <dd>
390
 
                <xsl:apply-templates select="comment" />
391
 
                <xsl:if test="count(./param) > 0">
392
 
                        <p>Arguments:</p>
393
 
                        <ul>
394
 
                                <xsl:apply-templates select="param" mode="comment" />
395
 
                                <li>variableName -
396
 
                    the name of a <a href="#storedVars">variable</a> in which the result is to be stored.
397
 
                </li>
398
 
                        </ul>
399
 
                </xsl:if>
400
 
                <xsl:apply-templates select="return" />
401
 
                <p>Related Assertions, automatically generated:</p>
402
 
                <ul>
403
 
                    <li> 
404
 
                                <xsl:call-template name="accessor-rename">
405
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
406
 
                                        <xsl:with-param name="prefix">assert</xsl:with-param>
407
 
                                </xsl:call-template>
408
 
                                (
409
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
410
 
                                        <xsl:if test="./return/@type != 'boolean'">
411
 
                                                <a href="#patterns">pattern</a>
412
 
                                        </xsl:if>
413
 
                                )
414
 
                        </li>
415
 
                        <li> 
416
 
                                <xsl:call-template name="accessor-rename">
417
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
418
 
                                        <xsl:with-param name="prefix">assertNot</xsl:with-param>
419
 
                                </xsl:call-template>
420
 
                                (
421
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
422
 
                                        <xsl:if test="./return/@type != 'boolean'">
423
 
                                                <a href="#patterns">pattern</a>
424
 
                                        </xsl:if>
425
 
                                )
426
 
                        </li>
427
 
                        <li>
428
 
                                <xsl:call-template name="accessor-rename">
429
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
430
 
                                        <xsl:with-param name="prefix">verify</xsl:with-param>
431
 
                                </xsl:call-template>
432
 
                                (
433
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
434
 
                                        <xsl:if test="./return/@type != 'boolean'">
435
 
                                                <a href="#patterns">pattern</a>
436
 
                                        </xsl:if>
437
 
                                )
438
 
                        </li>
439
 
                        <li>
440
 
                                <xsl:call-template name="accessor-rename">
441
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
442
 
                                        <xsl:with-param name="prefix">verifyNot</xsl:with-param>
443
 
                                </xsl:call-template>
444
 
                                (
445
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
446
 
                                        <xsl:if test="./return/@type != 'boolean'">
447
 
                                                <a href="#patterns">pattern</a>
448
 
                                        </xsl:if>
449
 
                                )
450
 
                        </li>
451
 
                        <li>
452
 
                                <xsl:call-template name="accessor-rename">
453
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
454
 
                                        <xsl:with-param name="prefix">waitFor</xsl:with-param>
455
 
                                </xsl:call-template>
456
 
                                (
457
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
458
 
                                        <xsl:if test="./return/@type != 'boolean'">
459
 
                                                <a href="#patterns">pattern</a>
460
 
                                        </xsl:if>
461
 
                                )
462
 
                        </li>
463
 
                        <li>
464
 
                                <xsl:call-template name="accessor-rename">
465
 
                                        <xsl:with-param name="accessor"><xsl:value-of select="@name" /></xsl:with-param>
466
 
                                        <xsl:with-param name="prefix">waitForNot</xsl:with-param>
467
 
                                </xsl:call-template>
468
 
                                (
469
 
                                        <xsl:apply-templates select="param" mode="declaration-assertion"/>
470
 
                                        <xsl:if test="./return/@type != 'boolean'">
471
 
                                                <a href="#patterns">pattern</a>
472
 
                                        </xsl:if>
473
 
                                )
474
 
                        </li>
475
 
                </ul>
476
 
                        
477
 
        </dd>
478
 
        <br/>
479
 
</xsl:template>
480
 
 
481
 
<xsl:template match="function" mode="action">
482
 
        <dt><strong>
483
 
            <a>
484
 
                <xsl:attribute name="name">
485
 
                    <xsl:value-of select="@name" />
486
 
                </xsl:attribute>
487
 
            </a>
488
 
                <xsl:value-of select="@name" />
489
 
                (
490
 
                        <xsl:apply-templates select="param" mode="declaration-action"/>
491
 
                )
492
 
        </strong></dt>
493
 
        <dd>
494
 
                <xsl:apply-templates select="comment" />
495
 
                <xsl:if test="count(./param) > 0">
496
 
                        <p>Arguments:</p>
497
 
                        <ul>
498
 
                                <xsl:apply-templates select="param" mode="comment" />
499
 
                        </ul>
500
 
                </xsl:if>
501
 
        </dd>
502
 
        <br/>
503
 
</xsl:template>
504
 
 
505
 
<!-- In action mode, don't print out a comma after the last argument -->
506
 
<xsl:template match="param" mode="declaration-action">
507
 
        <xsl:value-of select="@name" />
508
 
        <xsl:if test="position() != last()">
509
 
                <xsl:text>,</xsl:text>
510
 
        </xsl:if>
511
 
</xsl:template>
512
 
 
513
 
<!-- In accessor mode, always print out a comma, because we'll always append a final argument variableName -->
514
 
<xsl:template match="param" mode="declaration-accessor">
515
 
        <xsl:value-of select="@name" />,
516
 
</xsl:template>
517
 
 
518
 
<!-- In assertion mode, append a final pattern argument, unless the assertion is boolean, in which case no final argument -->
519
 
<xsl:template match="param" mode="declaration-assertion">
520
 
        <xsl:value-of select="@name" />
521
 
        <xsl:if test="position() != last() or ../return/@type != 'boolean'">
522
 
                <xsl:text>, </xsl:text>
523
 
        </xsl:if>
524
 
</xsl:template>
525
 
 
526
 
<xsl:template match="param" mode="comment">
527
 
        <li>
528
 
                <xsl:value-of select="@name" />
529
 
                <xsl:text> - </xsl:text>
530
 
                <xsl:apply-templates/>
531
 
        </li>
532
 
</xsl:template>
533
 
 
534
 
<xsl:template match="return">
535
 
    <p><dl><dt>Returns: </dt><dd><xsl:apply-templates/></dd></dl></p>
536
 
</xsl:template>
537
 
 
538
 
<!-- When we encounter anything else, just copy it right on over! -->
539
 
<xsl:template match="node()|@*" >
540
 
   <xsl:copy>
541
 
        <xsl:apply-templates select="node()|@*" />
542
 
   </xsl:copy>
543
 
</xsl:template> 
544
 
 
545
 
<!-- Take an accessor named getFoo or isFoo and replace it with a new prefix, e.g. storeFoo -->
546
 
<xsl:template name="accessor-rename">
547
 
        <xsl:param name="accessor"/>
548
 
    <xsl:param name="prefix"/>
549
 
    <xsl:variable name="spaced">&nbsp;<xsl:value-of select="$accessor" /></xsl:variable>
550
 
    <xsl:choose>
551
 
        <!-- If the accessor ends with "Present" and the prefix ends with "Not", then a simple replacement
552
 
        would get something ungrammatical, like assertNotTextPresent.  Instead, negate the prefix (assertNot becomes assert)
553
 
        and negate the accessor (TextPresent becomes TextNotPresent), so the command generated is
554
 
        assertTextNotPresent, which is much prettier -->
555
 
        <xsl:when test="contains(concat($prefix,'&nbsp;'),'Not&nbsp;') and contains(concat($accessor,'&nbsp;'),'Present&nbsp;')">
556
 
                <!-- negate the prefix -->
557
 
                <xsl:variable name="negatedPrefix">
558
 
                                <xsl:call-template name="search-and-replace">
559
 
                                        <xsl:with-param name="input"><xsl:value-of select='$prefix' />&nbsp;</xsl:with-param>
560
 
                                        <xsl:with-param name="search-string">Not&nbsp;</xsl:with-param>
561
 
                                        <xsl:with-param name="replace-string"></xsl:with-param>
562
 
                                </xsl:call-template>
563
 
                        </xsl:variable>
564
 
                        <!-- negate the accessor -->
565
 
                        <xsl:variable name="negatedAccessor">
566
 
                                <xsl:call-template name="search-and-replace">
567
 
                                        <xsl:with-param name="input"><xsl:value-of select='$accessor' />&nbsp;</xsl:with-param>
568
 
                                        <xsl:with-param name="search-string">Present&nbsp;</xsl:with-param>
569
 
                                        <xsl:with-param name="replace-string">NotPresent</xsl:with-param>
570
 
                                </xsl:call-template>
571
 
                        </xsl:variable>
572
 
                        <!-- replace "get" with the negated prefix -->
573
 
                        <xsl:variable name="getReplaced">
574
 
                                <xsl:call-template name="search-and-replace">
575
 
                                        <xsl:with-param name="input">&nbsp;<xsl:value-of select='$negatedAccessor' /></xsl:with-param>
576
 
                                        <xsl:with-param name="search-string">&nbsp;get</xsl:with-param>
577
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$negatedPrefix' /></xsl:with-param>
578
 
                                </xsl:call-template>
579
 
                        </xsl:variable>
580
 
                        <!-- replace "is" with the negated prefix -->
581
 
                        <xsl:variable name="isReplaced">
582
 
                                <xsl:call-template name="search-and-replace">
583
 
                                        <xsl:with-param name="input"><xsl:value-of select='$getReplaced' /></xsl:with-param>
584
 
                                        <xsl:with-param name="search-string">&nbsp;is</xsl:with-param>
585
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$negatedPrefix' /></xsl:with-param>
586
 
                                </xsl:call-template>
587
 
                        </xsl:variable>
588
 
                        <!-- replace "assert" with the negated prefix -->
589
 
                        <xsl:variable name="assertReplaced">
590
 
                                <xsl:call-template name="search-and-replace">
591
 
                                        <xsl:with-param name="input"><xsl:value-of select='$isReplaced' /></xsl:with-param>
592
 
                                        <xsl:with-param name="search-string">&nbsp;assert</xsl:with-param>
593
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$negatedPrefix' /></xsl:with-param>
594
 
                                </xsl:call-template>
595
 
                        </xsl:variable>
596
 
                        <!-- and print out the output -->
597
 
                        <xsl:value-of select="$assertReplaced"/>
598
 
        </xsl:when>
599
 
        <xsl:otherwise>
600
 
                <!-- replace "get" with the prefix -->
601
 
                    <xsl:variable name="getReplaced">
602
 
                                <xsl:call-template name="search-and-replace">
603
 
                                        <xsl:with-param name="input">&nbsp;<xsl:value-of select='$accessor' /></xsl:with-param>
604
 
                                        <xsl:with-param name="search-string">&nbsp;get</xsl:with-param>
605
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$prefix' /></xsl:with-param>
606
 
                                </xsl:call-template>
607
 
                        </xsl:variable>
608
 
                        <!-- replace "is" with the prefix -->
609
 
                        <xsl:variable name="isReplaced">
610
 
                                <xsl:call-template name="search-and-replace">
611
 
                                        <xsl:with-param name="input"><xsl:value-of select='$getReplaced' /></xsl:with-param>
612
 
                                        <xsl:with-param name="search-string">&nbsp;is</xsl:with-param>
613
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$prefix' /></xsl:with-param>
614
 
                                </xsl:call-template>
615
 
                        </xsl:variable>
616
 
                        <!-- replace "assert" with the prefix -->
617
 
                        <xsl:variable name="assertReplaced">
618
 
                                <xsl:call-template name="search-and-replace">
619
 
                                        <xsl:with-param name="input"><xsl:value-of select='$isReplaced' /></xsl:with-param>
620
 
                                        <xsl:with-param name="search-string">&nbsp;assert</xsl:with-param>
621
 
                                        <xsl:with-param name="replace-string"><xsl:value-of select='$prefix' /></xsl:with-param>
622
 
                                </xsl:call-template>
623
 
                        </xsl:variable>
624
 
                        <!-- and print out the output -->
625
 
                        <xsl:value-of select="$assertReplaced"/>
626
 
                </xsl:otherwise>
627
 
        </xsl:choose>
628
 
        
629
 
</xsl:template>
630
 
 
631
 
 
632
 
<xsl:template name="search-and-replace">
633
 
     <xsl:param name="input"/>
634
 
     <xsl:param name="search-string"/>
635
 
     <xsl:param name="replace-string"/>
636
 
     <xsl:choose>
637
 
          <!-- See if the input contains the search string -->
638
 
          <xsl:when test="$search-string and 
639
 
                           contains($input,$search-string)">
640
 
          <!-- If so, then concatenate the substring before the search
641
 
          string to the replacement string and to the result of
642
 
          recursively applying this template to the remaining substring.
643
 
          -->
644
 
               <xsl:value-of 
645
 
                    select="substring-before($input,$search-string)"/>
646
 
               <xsl:value-of select="$replace-string"/>
647
 
               <xsl:call-template name="search-and-replace">
648
 
                    <xsl:with-param name="input"
649
 
                    select="substring-after($input,$search-string)"/>
650
 
                    <xsl:with-param name="search-string" 
651
 
                    select="$search-string"/>
652
 
                    <xsl:with-param name="replace-string" 
653
 
                        select="$replace-string"/>
654
 
               </xsl:call-template>
655
 
          </xsl:when>
656
 
          <xsl:otherwise>
657
 
               <!-- There are no more occurrences of the search string so 
658
 
               just return the current input string -->
659
 
               <xsl:value-of select="$input"/>
660
 
          </xsl:otherwise>
661
 
     </xsl:choose>
662
 
</xsl:template>
663
 
 
664
 
</xsl:stylesheet>
 
 
b'\\ No newline at end of file'