From 1fcb71a6a18e332eb6410b85aa8b812795087c08 Mon Sep 17 00:00:00 2001 From: wei <> Date: Wed, 31 May 2006 04:37:17 +0000 Subject: Remove old selenium. --- .gitattributes | 55 - tests/FunctionalTests/selenium/SeleneseRunner.html | 97 - tests/FunctionalTests/selenium/SeleniumLog.html | 61 - .../selenium/TestRunner-splash.html | 55 - tests/FunctionalTests/selenium/TestRunner.hta | 146 - tests/FunctionalTests/selenium/TestRunner.html | 146 - tests/FunctionalTests/selenium/VERSION.txt | 1 - tests/FunctionalTests/selenium/build.xml | 109 - tests/FunctionalTests/selenium/doc/FAQ.html | 128 - tests/FunctionalTests/selenium/doc/FAQ.txt | 127 - tests/FunctionalTests/selenium/doc/contact.html | 23 - .../selenium/doc/developingdrivers.html | 134 - tests/FunctionalTests/selenium/doc/driven.html | 206 - tests/FunctionalTests/selenium/doc/home-page.html | 161 - .../selenium/doc/images/Adjacent.png | Bin 39287 -> 0 bytes .../selenium/doc/images/Embedded.png | Bin 30678 -> 0 bytes .../selenium/doc/images/SmallAdjacent.png | Bin 12067 -> 0 bytes .../selenium/doc/images/SmallEmbedded.png | Bin 6141 -> 0 bytes .../selenium/doc/images/SmallStandalone.png | Bin 7336 -> 0 bytes .../selenium/doc/images/Standalone.png | Bin 38131 -> 0 bytes .../selenium/doc/images/localhostAut.png | Bin 4474 -> 0 bytes .../selenium/doc/images/localhostDriver.png | Bin 3865 -> 0 bytes .../selenium/doc/images/localhostSelenium.png | Bin 3600 -> 0 bytes .../selenium/doc/images/stockmeister.png | Bin 6514 -> 0 bytes .../selenium/doc/images/tested-with-selenium.png | Bin 3294 -> 0 bytes tests/FunctionalTests/selenium/doc/index.html | 30 - tests/FunctionalTests/selenium/doc/jsrmi.html | 151 - .../selenium/doc/release-notes.html | 97 - tests/FunctionalTests/selenium/doc/rst2html.bat | 3 - .../selenium/doc/seleniumReference.html | 1148 ------ .../selenium/doc/seleniumReference.txt | 771 ---- tests/FunctionalTests/selenium/doc/testRunner.txt | 99 - tests/FunctionalTests/selenium/doc/testrunner.html | 213 - tests/FunctionalTests/selenium/doc/usage.html | 84 - tests/FunctionalTests/selenium/domviewer.html | 16 - tests/FunctionalTests/selenium/htmlutils.js | 283 -- tests/FunctionalTests/selenium/index.html | 60 - tests/FunctionalTests/selenium/install-readme.txt | 9 - .../selenium/readme-selenium-fitrunner.txt | 46 - .../selenium/readme-selenium-rpcrunner.txt | 17 - tests/FunctionalTests/selenium/selenium-api.js | 739 ---- .../selenium/selenium-browserbot.js | 1001 ----- .../selenium/selenium-commandhandlers.js | 291 -- .../FunctionalTests/selenium/selenium-domviewer.js | 188 - .../selenium/selenium-executionloop.js | 234 -- .../FunctionalTests/selenium/selenium-fitrunner.js | 597 --- tests/FunctionalTests/selenium/selenium-logging.js | 88 - .../FunctionalTests/selenium/selenium-logo.graffle | 509 --- tests/FunctionalTests/selenium/selenium-logo.png | Bin 6714 -> 0 bytes .../selenium/selenium-seleneserunner.js | 172 - .../selenium/selenium-tableparser.js | 50 - .../selenium/selenium-testrunner.js | 597 --- tests/FunctionalTests/selenium/selenium.css | 211 - .../selenium/user-extensions.js.sample | 62 - tests/FunctionalTests/selenium/xmlextras.js | 153 - tests/FunctionalTests/selenium/xpath.js | 4169 -------------------- 56 files changed, 13537 deletions(-) delete mode 100644 tests/FunctionalTests/selenium/SeleneseRunner.html delete mode 100644 tests/FunctionalTests/selenium/SeleniumLog.html delete mode 100644 tests/FunctionalTests/selenium/TestRunner-splash.html delete mode 100644 tests/FunctionalTests/selenium/TestRunner.hta delete mode 100644 tests/FunctionalTests/selenium/TestRunner.html delete mode 100644 tests/FunctionalTests/selenium/VERSION.txt delete mode 100644 tests/FunctionalTests/selenium/build.xml delete mode 100644 tests/FunctionalTests/selenium/doc/FAQ.html delete mode 100644 tests/FunctionalTests/selenium/doc/FAQ.txt delete mode 100644 tests/FunctionalTests/selenium/doc/contact.html delete mode 100644 tests/FunctionalTests/selenium/doc/developingdrivers.html delete mode 100644 tests/FunctionalTests/selenium/doc/driven.html delete mode 100644 tests/FunctionalTests/selenium/doc/home-page.html delete mode 100644 tests/FunctionalTests/selenium/doc/images/Adjacent.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/Embedded.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/SmallAdjacent.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/SmallEmbedded.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/SmallStandalone.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/Standalone.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/localhostAut.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/localhostDriver.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/localhostSelenium.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/stockmeister.png delete mode 100644 tests/FunctionalTests/selenium/doc/images/tested-with-selenium.png delete mode 100644 tests/FunctionalTests/selenium/doc/index.html delete mode 100644 tests/FunctionalTests/selenium/doc/jsrmi.html delete mode 100644 tests/FunctionalTests/selenium/doc/release-notes.html delete mode 100644 tests/FunctionalTests/selenium/doc/rst2html.bat delete mode 100644 tests/FunctionalTests/selenium/doc/seleniumReference.html delete mode 100644 tests/FunctionalTests/selenium/doc/seleniumReference.txt delete mode 100644 tests/FunctionalTests/selenium/doc/testRunner.txt delete mode 100644 tests/FunctionalTests/selenium/doc/testrunner.html delete mode 100644 tests/FunctionalTests/selenium/doc/usage.html delete mode 100644 tests/FunctionalTests/selenium/domviewer.html delete mode 100644 tests/FunctionalTests/selenium/htmlutils.js delete mode 100644 tests/FunctionalTests/selenium/index.html delete mode 100644 tests/FunctionalTests/selenium/install-readme.txt delete mode 100644 tests/FunctionalTests/selenium/readme-selenium-fitrunner.txt delete mode 100644 tests/FunctionalTests/selenium/readme-selenium-rpcrunner.txt delete mode 100644 tests/FunctionalTests/selenium/selenium-api.js delete mode 100644 tests/FunctionalTests/selenium/selenium-browserbot.js delete mode 100644 tests/FunctionalTests/selenium/selenium-commandhandlers.js delete mode 100644 tests/FunctionalTests/selenium/selenium-domviewer.js delete mode 100644 tests/FunctionalTests/selenium/selenium-executionloop.js delete mode 100644 tests/FunctionalTests/selenium/selenium-fitrunner.js delete mode 100644 tests/FunctionalTests/selenium/selenium-logging.js delete mode 100644 tests/FunctionalTests/selenium/selenium-logo.graffle delete mode 100644 tests/FunctionalTests/selenium/selenium-logo.png delete mode 100644 tests/FunctionalTests/selenium/selenium-seleneserunner.js delete mode 100644 tests/FunctionalTests/selenium/selenium-tableparser.js delete mode 100644 tests/FunctionalTests/selenium/selenium-testrunner.js delete mode 100644 tests/FunctionalTests/selenium/selenium.css delete mode 100644 tests/FunctionalTests/selenium/user-extensions.js.sample delete mode 100644 tests/FunctionalTests/selenium/xmlextras.js delete mode 100644 tests/FunctionalTests/selenium/xpath.js diff --git a/.gitattributes b/.gitattributes index d1f25263..14e89e74 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1038,13 +1038,6 @@ tests/FunctionalTests/quickstart/Controls/Wizard3TestCase.php -text tests/FunctionalTests/quickstart/Controls/Wizard4TestCase.php -text tests/FunctionalTests/quickstart/Controls/Wizard5TestCase.php -text tests/FunctionalTests/quickstart/Fundamentals/HangmanTestCase.php -text -tests/FunctionalTests/selenium/SeleneseRunner.html -text -tests/FunctionalTests/selenium/SeleniumLog.html -text -tests/FunctionalTests/selenium/TestRunner-splash.html -text -tests/FunctionalTests/selenium/TestRunner.hta -text -tests/FunctionalTests/selenium/TestRunner.html -text -tests/FunctionalTests/selenium/VERSION.txt -text -tests/FunctionalTests/selenium/build.xml -text tests/FunctionalTests/selenium/core/SeleneseRunner.html -text tests/FunctionalTests/selenium/core/SeleniumLog.html -text tests/FunctionalTests/selenium/core/TestPrompt.html -text @@ -1074,69 +1067,21 @@ tests/FunctionalTests/selenium/core/selenium.css -text tests/FunctionalTests/selenium/core/xpath/dom.js -text tests/FunctionalTests/selenium/core/xpath/misc.js -text tests/FunctionalTests/selenium/core/xpath/xpath.js -text -tests/FunctionalTests/selenium/doc/FAQ.html -text -tests/FunctionalTests/selenium/doc/FAQ.txt -text -tests/FunctionalTests/selenium/doc/contact.html -text -tests/FunctionalTests/selenium/doc/developingdrivers.html -text -tests/FunctionalTests/selenium/doc/driven.html -text -tests/FunctionalTests/selenium/doc/home-page.html -text -tests/FunctionalTests/selenium/doc/images/Adjacent.png -text -tests/FunctionalTests/selenium/doc/images/Embedded.png -text -tests/FunctionalTests/selenium/doc/images/SmallAdjacent.png -text -tests/FunctionalTests/selenium/doc/images/SmallEmbedded.png -text -tests/FunctionalTests/selenium/doc/images/SmallStandalone.png -text -tests/FunctionalTests/selenium/doc/images/Standalone.png -text -tests/FunctionalTests/selenium/doc/images/localhostAut.png -text -tests/FunctionalTests/selenium/doc/images/localhostDriver.png -text -tests/FunctionalTests/selenium/doc/images/localhostSelenium.png -text -tests/FunctionalTests/selenium/doc/images/stockmeister.png -text -tests/FunctionalTests/selenium/doc/images/tested-with-selenium.png -text -tests/FunctionalTests/selenium/doc/index.html -text -tests/FunctionalTests/selenium/doc/jsrmi.html -text -tests/FunctionalTests/selenium/doc/release-notes.html -text -tests/FunctionalTests/selenium/doc/rst2html.bat -text -tests/FunctionalTests/selenium/doc/seleniumReference.html -text -tests/FunctionalTests/selenium/doc/seleniumReference.txt -text -tests/FunctionalTests/selenium/doc/testRunner.txt -text -tests/FunctionalTests/selenium/doc/testrunner.html -text -tests/FunctionalTests/selenium/doc/usage.html -text tests/FunctionalTests/selenium/dom-images/butmin.gif -text tests/FunctionalTests/selenium/dom-images/butplus.gif -text tests/FunctionalTests/selenium/dom-styles/default.css -text -tests/FunctionalTests/selenium/domviewer.html -text tests/FunctionalTests/selenium/html-xpath/carnation.jpg -text tests/FunctionalTests/selenium/html-xpath/example.html -text tests/FunctionalTests/selenium/html-xpath/html-xpath-patched.js -text tests/FunctionalTests/selenium/html-xpath/html-xpath.js -text tests/FunctionalTests/selenium/html-xpath/license.txt -text tests/FunctionalTests/selenium/html-xpath/rainbow.jpg -text -tests/FunctionalTests/selenium/htmlutils.js -text -tests/FunctionalTests/selenium/index.html -text -tests/FunctionalTests/selenium/install-readme.txt -text tests/FunctionalTests/selenium/jsmock/mock-tests.html -text tests/FunctionalTests/selenium/jsmock/mock.js -text tests/FunctionalTests/selenium/php/TestRunner.php -text tests/FunctionalTests/selenium/php/results.php -text tests/FunctionalTests/selenium/php/selenium.php -text tests/FunctionalTests/selenium/prado-functional-test.js -text -tests/FunctionalTests/selenium/readme-selenium-fitrunner.txt -text -tests/FunctionalTests/selenium/readme-selenium-rpcrunner.txt -text -tests/FunctionalTests/selenium/selenium-api.js -text -tests/FunctionalTests/selenium/selenium-browserbot.js -text -tests/FunctionalTests/selenium/selenium-commandhandlers.js -text -tests/FunctionalTests/selenium/selenium-domviewer.js -text -tests/FunctionalTests/selenium/selenium-executionloop.js -text -tests/FunctionalTests/selenium/selenium-fitrunner.js -text -tests/FunctionalTests/selenium/selenium-logging.js -text -tests/FunctionalTests/selenium/selenium-logo.graffle -text -tests/FunctionalTests/selenium/selenium-logo.png -text -tests/FunctionalTests/selenium/selenium-seleneserunner.js -text -tests/FunctionalTests/selenium/selenium-tableparser.js -text -tests/FunctionalTests/selenium/selenium-testrunner.js -text -tests/FunctionalTests/selenium/selenium.css -text -tests/FunctionalTests/selenium/user-extensions.js.sample -text -tests/FunctionalTests/selenium/xmlextras.js -text -tests/FunctionalTests/selenium/xpath.js -text tests/FunctionalTests/tickets.php -text tests/FunctionalTests/tickets/index.php -text tests/FunctionalTests/tickets/protected/pages/Layout.php -text diff --git a/tests/FunctionalTests/selenium/SeleneseRunner.html b/tests/FunctionalTests/selenium/SeleneseRunner.html deleted file mode 100644 index 4ace34c7..00000000 --- a/tests/FunctionalTests/selenium/SeleneseRunner.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - -Selenium Functional Test Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - -
- - -

Selenium Functional Testing for Web Apps

- Open Source From ThoughtWorks, Inc and Friends -
-
Slow Mode: - -
- Tools - - - -
- -
- -
-
- -
-
- Last Four Commands
-
-
- -
- - - - diff --git a/tests/FunctionalTests/selenium/SeleniumLog.html b/tests/FunctionalTests/selenium/SeleniumLog.html deleted file mode 100644 index 01a5a9fe..00000000 --- a/tests/FunctionalTests/selenium/SeleniumLog.html +++ /dev/null @@ -1,61 +0,0 @@ - - - -Selenium Log Console - - - - - - - - - - - - - diff --git a/tests/FunctionalTests/selenium/TestRunner-splash.html b/tests/FunctionalTests/selenium/TestRunner-splash.html deleted file mode 100644 index 3abd1ec8..00000000 --- a/tests/FunctionalTests/selenium/TestRunner-splash.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
Test SuiteCurrent TestControl Panel
 
- - - -

Selenium

-

by ThoughtWorks and friends

- -

-For more information on Selenium, visit - -

-    http://selenium.thoughtworks.com
-
- -
- - diff --git a/tests/FunctionalTests/selenium/TestRunner.hta b/tests/FunctionalTests/selenium/TestRunner.hta deleted file mode 100644 index e4516243..00000000 --- a/tests/FunctionalTests/selenium/TestRunner.hta +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - -Selenium Functional Test Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Selenium TestRunner

-
- -
- Execute Tests - -
- - - -
- -
- - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Elapsed:00.00
TestsCommands
0run0passed
0failed0failed
0incomplete
- -
- Tools - - - - -
- -
- - - diff --git a/tests/FunctionalTests/selenium/TestRunner.html b/tests/FunctionalTests/selenium/TestRunner.html deleted file mode 100644 index c476f25e..00000000 --- a/tests/FunctionalTests/selenium/TestRunner.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - -Selenium Functional Test Runner - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Selenium TestRunner

-
- -
- Execute Tests - -
- - - -
- -
- - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Elapsed:00.00
TestsCommands
0run0passed
0failed0failed
0incomplete
- -
- Tools - - - - -
- -
- - - diff --git a/tests/FunctionalTests/selenium/VERSION.txt b/tests/FunctionalTests/selenium/VERSION.txt deleted file mode 100644 index 2d589f48..00000000 --- a/tests/FunctionalTests/selenium/VERSION.txt +++ /dev/null @@ -1 +0,0 @@ -trunk (SVN/UNRELEASED) \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/build.xml b/tests/FunctionalTests/selenium/build.xml deleted file mode 100644 index 73376a1e..00000000 --- a/tests/FunctionalTests/selenium/build.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create a TestSuite.html page, and a number of test pages here. Read the docs! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/FunctionalTests/selenium/doc/FAQ.html b/tests/FunctionalTests/selenium/doc/FAQ.html deleted file mode 100644 index 90299653..00000000 --- a/tests/FunctionalTests/selenium/doc/FAQ.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - -Selenium Frequently Asked Questions - - - -

Selenium Frequently Asked Questions

-
- -

This is a work in progress. Please feel free to ask questions and/or -provide answers; send email to the Selenium users email address at selenium-users@lists.public.thoughtworks.org.

- -
-

1   Selenium

-
-

1.1   What is Selenium used for?

-

It is used for functional or system testing web applications. These tests -are also sometimes called acceptance, customer, or integration tests. Selenium is not meant for unit testing.

-
-
-

1.2   Why can't I script google.com?

-

Question: -I was trying to write a simple script that does a google search. -I have been running into all sorts of problems. Does this work for you? -Here is my test: - - - - - - - - - - - - - - - - - - - - -
Test Type
-
openhttp://www.google.com/ 
typeqtesting tools
clicksubmitButton 
.

-

Answer: -The quick answer is that because of cross-site scripting security built into -JavaScript engines in all browsers, you can't edit the content of a web page -from another domain. The foreign page will probably load correctly and be visible -in the test runner window, but Selenium won't be able to query or edit its contents. -In other words, you can't run selenium on "foo.com" and -run a test that edits values and clicks buttons against "bar.com". So, in -its current form, you can't "script" google.com because your script isn't -currently hosted on google.com. When Selenium and the application you are -testing is hosted on the same domain, however, you do not run into the -cross-site scripting security feature/limitation.

-

You read more about cross-site scripting here: http://www.devarticles.com/c/a/JavaScript/JavaScript-Security/

-

Also, if cross-site scripting security didn't exist, be careful about your -field and button references in your tests. The current version -of Selenium uses the "id" attribute of the object you are referring to in your -test. The search field and submit button at google.com have "name" attributes, -but not not "id" attributes. Therefore, Selenium wouldn't be able to find the objects. -Future versions of Selenium will be able to search for objects by more than -just the id attribute, though.

-
-
-

1.3   How can I run my test against a foreign or remote server and get around cross-site scripting security?

-

There are a few ways around cross-site scripting to access a remote server. -You could use a combination of proxying and URL rewriting in Apache to -trick the browser into the thinking the application and the testing tool -are coming from the same domain.

-

Another option is to run Selenium as an "HTA" application, or "HTML -Application" in Internet Explorer. HTA applications run in the security -context of any trusted application on the client, so there is no cross-site -scripting limitation. (You can find out more here: -http://msdn.microsoft.com/workshop/author/hta/overview/htaoverview.asp) The -equivalent to this "security-free" client on the Mozilla side of the fence -would be to write a XUL wrapper/extension.

-

Also, please see the answer to the related question: "Why can't I script google.com".

-
-
-

1.4   How do you create test tables?

-

The developers on the Selenium project use Mozilla Composer to -create plain HTML text files for their tests. -By default, Mozilla Composer writes very clean HTML without any extra, unnecessary markup.

-

Future versions of Selenium may support RST (ReStructred Text), or wiki-table -syntax, natively. However, you are free to use another format now, -as long as you remember to generate the HTML files from your source files, -either during your build process or dynamically at run-time.

- --- - - - - - - - - - -
Author:Jason Huggins
Created Date:11/05/2004
Modified Date:11/05/2004
Created With:reStructuredText: http://docutils.sourceforge.net/rst.html
-
-
-
- - diff --git a/tests/FunctionalTests/selenium/doc/FAQ.txt b/tests/FunctionalTests/selenium/doc/FAQ.txt deleted file mode 100644 index ad9894ee..00000000 --- a/tests/FunctionalTests/selenium/doc/FAQ.txt +++ /dev/null @@ -1,127 +0,0 @@ -=========================================== - Selenium Frequently Asked Questions -=========================================== - -.. Please note that until there's a Q&A-specific construct available, - this FAQ will use section titles for questions. Therefore - questions must fit on one line. The title may be a summary of the - question, with the full question in the section body. - -This is a work in progress. Please feel free to ask questions and/or -provide answers; send email to the Selenium users email address at `selenium-users@lists.public.thoughtworks.org`__. - -.. _let us know: -__ mailto:selenium-users@lists.public.thoughtworks.org - - -.. contents:: -.. sectnum:: - - - - -Selenium -======== - -What is Selenium used for? --------------------------- - -It is used for functional or system testing web applications. These tests -are also sometimes called acceptance, customer, or integration tests. Selenium is not meant for unit testing. - - - -Why can't I script google.com? ------------------------------- -Question: -*I was trying to write a simple script that does a google search. -I have been running into all sorts of problems. Does this work for you? -Here is my test:* |test|. - -.. |test| raw:: html - - - - - - - - - - - - - - - - - - - - - - -
Test Type
-
openhttp://www.google.com/ 
typeqtesting tools
clicksubmitButton 
- -Answer: -The quick answer is that because of cross-site scripting security built into -JavaScript engines in all browsers, you can't edit the content of a web page -from another domain. The foreign page will probably load correctly and be visible -in the test runner window, but Selenium won't be able to query or edit its contents. -In other words, you can't run selenium on "foo.com" and -run a test that edits values and clicks buttons against "bar.com". So, in -its current form, you can't "script" google.com because your script isn't -currently hosted on google.com. When Selenium and the application you are -testing is hosted on the same domain, however, you do not run into the -cross-site scripting security feature/limitation. - -You read more about cross-site scripting here: http://www.devarticles.com/c/a/JavaScript/JavaScript-Security/ - -Also, if cross-site scripting security didn't exist, be careful about your -field and button references in your tests. The current version -of Selenium uses the "id" attribute of the object you are referring to in your -test. The search field and submit button at google.com have "name" attributes, -but not not "id" attributes. Therefore, Selenium wouldn't be able to find the objects. -Future versions of Selenium will be able to search for objects by more than -just the id attribute, though. - - -How can I run my test against a foreign or remote server and get around cross-site scripting security? ------------------------------------------------------------------------------------------------------- - -There are a few ways around cross-site scripting to access a remote server. -You could use a combination of proxying and URL rewriting in Apache to -trick the browser into the thinking the application and the testing tool -are coming from the same domain. - -Another option is to run Selenium as an "HTA" application, or "HTML -Application" in Internet Explorer. HTA applications run in the security -context of any trusted application on the client, so there is no cross-site -scripting limitation. (You can find out more here: -http://msdn.microsoft.com/workshop/author/hta/overview/htaoverview.asp) The -equivalent to this "security-free" client on the Mozilla side of the fence -would be to write a XUL wrapper/extension. - -Also, please see the answer to the related question: "Why can't I script google.com". - - -How do you create test tables? ------------------------------- - -The developers on the Selenium project use Mozilla Composer to -create plain HTML text files for their tests. -By default, Mozilla Composer writes very clean HTML without any extra, unnecessary markup. - -Future versions of Selenium may support RST (ReStructred Text), or wiki-table -syntax, natively. However, you are free to use another format now, -as long as you remember to generate the HTML files from your source files, -either during your build process or dynamically at run-time. - - - -:Author: - Jason Huggins -:Created Date: 11/05/2004 -:Modified Date: 11/05/2004 -:Created With: reStructuredText: http://docutils.sourceforge.net/rst.html \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/doc/contact.html b/tests/FunctionalTests/selenium/doc/contact.html deleted file mode 100644 index b109444d..00000000 --- a/tests/FunctionalTests/selenium/doc/contact.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Selenium Contact - - -

-For more information about Selenium, please use Confluence and the standard mailing lists below. -

-

Selenium Project Wiki

-[ Selenium Confluence ] -

-

Selenium Development

-selenium-devel-subscribe@lists.public.thoughtworks.org
-[ Subscribe/Unsubscribe | Message Archives ] -

-

Selenium Users

-selenium-users-subscribe@lists.public.thoughtworks.org
-[ Subscribe/Unsubscribe | Message Archives ] - - diff --git a/tests/FunctionalTests/selenium/doc/developingdrivers.html b/tests/FunctionalTests/selenium/doc/developingdrivers.html deleted file mode 100644 index 4c2594d9..00000000 --- a/tests/FunctionalTests/selenium/doc/developingdrivers.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Developing Drivers - - -

Overview

-This page details important information for people developing drivers -for Selenium.
-

Same Origin Policy

-This is a security issue that affects all modern browsers. It is well -described here, -but for our purposes, it constrains the way that a -JavaScript in a browser may interoperate with other open frames and -windows. In short, the Selenium JavaScript app must come from (or -appear to) the same origin as the AUT.
-

The Driver

-The driver has a number of duties. These are typically..
- -

Local, Remote and URLs
-

-An application may be testable in a remote location by humans, but for -scripted testing and the need for the driver to dynamically drive the -browser, it is optimal for the driver to be on the same machine as that -serving the AUT and the browser testing it. 
-
-Thus, an application as deployed ...
-
-http://localhost:8080/
-
-... would appear like so for the purposes of testing ...
-
-http://localhost:8080/
-
-As with the standalone version of Selenium, there are a number of files -(HTML and JavaScript) that comprise the bulk of the testing framework -and sit in the browser as testing occurs. It makes most sense to put -these in a virtual directory on the same server ...
-
-http://localhost:8080/selenium/
-
-The dynamic webapp needs to be similarly mounted ...
-
-http://localhost:8080/selenium/driver?...
-
-As the dynamic is the link between what is happening in the browser and -the driving process, it we need to somehow have an instance reference -to it.  This is easier in some languages and web servers than -others.  Also full programatic start/stop control over the web -server is not always possible for some larger web servers -implementations.
-

Reply/Request Architecture

-Because a browser cannot open a socket and listen on it, we must -effectively initiate communication thru the driver on the browser side. -Ignoring the possibilities granted by keep-alive, we simply poll from -the browser to the server and pick up commands to process inside the -browser.  Results of commands are also passed back to the dynamic -hander over the same mechanism. These are in fact done in the same HTTP -request.  The results from the previous -command go back as query string parameters, and the next command is communicated in a -text/plain document
-
-The previous/next business introduces some complexity on the driver -side of the design. Namely hidden behind the API, the driver must -manage queues for the outgoing commands and the (some time later) -incoming responses.  Java, until 1.5, did not have a blocking -queue to make this easy. Most other languages did.
-

Selenese

- - - - - - - -
Selenese is the contrived (and mostly hidden) wire language -that the -driver uses to speak to the browser-bot through the dynamic -handler. It uses HTTP for its transport, and is quite -simple.
-
-Responses come from the browser to the driver in a query -string like  
-
commandResult=OK,
-
-Commands go from the driver to the -browser-bot in a text/plain document:
-
| open | /foo/bar.html | |
-
-This two way communication is of course invisible to the observer.
The -BrowserBot, by understanding Selenese, allows a process other than the -browser itsself to direct events on the Application Under Test. 
-
-The Selenese language is simple enough to be commandable by any -language that has an API that can handle HTTP requests.
-
-Thus, Selenese allows many different open, free or closed license -drivers to interoperate with the BrowserBot.
-

Choregraphy

-The driver cleary has some fairly heavy things to do.  It is -important for some robustness to be built into the design. For example -it may take a long time for the browser to be instantiated on a -particular platform.  It is appropriate for wait timeouts to be -generous here.  Similarly whilst issuing individual commands it is -important for the driver to wait a sufficient amount of time for a -command to execute (and its result to come back).  For the most -part on a localhost setup, it will be because the AUT is slow, but it -could be because some break in the app means that there will be no -subsequent response.  Some timeout regime should be able to -recover from, mark a test as failed (for reasons of timeout), and start -again with the next test.
-
-
- - diff --git a/tests/FunctionalTests/selenium/doc/driven.html b/tests/FunctionalTests/selenium/doc/driven.html deleted file mode 100644 index a5f33dff..00000000 --- a/tests/FunctionalTests/selenium/doc/driven.html +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - Driven Selenium Reference - - - -
-
-

Overview

-Driven Selenium is where the browser is under the the control of an -adjacent process. That process is either a Java, .Net, Ruby or Python -application and it is typically run in conjunction with a unit testing -framework like JUnit or NUnit. Also possible, is a console application -driving a browser interactively.
-

Selenium & Selenese

-The key to this mode of operation is manner in which the browset-bot -takes instruction from the driver.  If it were possible, the -browser-bot's javascript would open a server socket and await requests -from the driver. It is against the rules for browser embedded -javascript, to open ports for incoking requests as it would be a -general breach of security for the client-OS that the browser is -running on.  What a browser can do is open addition requests to -the same server that its source came from. See http://www.mozilla.org/projects/security/components/same-origin.html -for more info.
-
-To overcome the limitations of Javascript in a browser page is the page -continuously requests pages from the driver (which has conveniently -opened a web server). The pages which are retrieved from the server are -in fact plain text and each is an individual instruction from the -driver for what the browser-bot is to do next.  E.g. -
-
-    | open | /foo/bar.html | |
-
-We refer to this architecture are reply/request rather than the more -ususal request/reply.
-

Sample test method
-

-The test script is one that would be recognisable to people adept with -unit test frameworks :
-
-For Java -
-
-  public void testOKClick() {
-    selenium.verifyTitle("First Page");
-    selenium.open("/TestPage.html");
-    selenium.click("OKButton");
-    selenium.verifyTitle("Another Page");
-  }
-
-The difference from normal unit testing is that as part of the startup, -three major things have to happen:
-
    -
  1. The test framework needs to publish a fresh copy of the -Application Under Test (AUT). -Selenium prefers to mount its own web server temporarily for the -purposes of testing.
  2. -
  3. The test framework needs to publish the static Selenium pages -(refer selenium dir in TestRunner mode above) in an apparent directory -on the same web server as (1).
  4. -
  5. The test framework needs to open a browser instance and point it -to Selenium.html served in (2) above.
  6. -
-As each of these isa fairly time consuming operation, it is best that -all three of those happen in a one time setup mode.  As such, and -even though these leverage a unit testing framework, this is definately -for acceptance or functional testing.
-

Example Setup
-

-
-
For Java -
-
-   selenium = new DefaultSelenium("c:\foo\bar-web-app\");
-
-The above will instantiate a web server using Jetty, and -publish it at http://localhost:8080. The Selenium pages will appear to -be run from http://localhost:8080/selenium-driver. The default browser -for Windows, Linux or Mac will be instantiated and directed to accept -test instructions from the driver.
-
-The above would ususally be done in a setup method if under unit test -control.  See http://junit.sourceforge.net/doc/faq/faq.htm#organize_3 -for advice on one time setup for Java.

-A more complex case could be -
-
-  selenium = new DefaultSelenium(new -TomcatCommandProcessor("c:\foo\bar-web-app"), new -MyOperaBrowserLauncher()),
-

Command Reference

-    void chooseCancelOnNextConfirmation();
-    void click(String field);
-    void clickAndWait(String field);
-    void open(String path);
-    void pause(int duration);
-    void selectAndWait(String field, String value);
-    void selectWindow(String window);
-    void setTextField(String field, String value);
-    void storeText(String element, String value);
-    void storeValue(String field, String value);
-    void testComplete();
-    void type(String field, String value);
-    void typeAndWait(String field, String value);
-    void verifyAlert(String alert);
-    void verifyAttribute(String element, String value);
-    void verifyConfirmation(String confirmation);
-    void verifyElementNotPresent(String type);
-    void verifyElementPresent(String type);
-    void verifyLocation(String location);
-    void verifySelectOptions(String field, String[] -values);
-    void verifySelected(String field, String value);
-    void verifyTable(String table, String value);
-    void verifyText(String type, String text);
-    void verifyTextPresent(String type, String text);
-    void verifyTitle(String title);
-    void verifyValue(String field, String value);
-

Deployment Choices

-

Embedded Web Server

-

-Picture of Browser and Driving process
-The best way to deply the driven form of Selenium is where an embedded -web server is used. With the Java version, this could be Jetty or Tomcat.
-
-In advance of a series of selenese instructions being issued to the -browser, a web server containing the AUT and some static pages for -Selenium itself will be programmatically started and used to -communicate selenese instructions to the browser.  When the driver -process is complete the web server will be programmatically stopped.
-

-

[ For release 0.2 - this is the only -mode that really works. Those below will be fine for 0.3 and above ]
-

-

Adjacent Web Server

-diagram of adjacent config
-By adjacent we mean a process on the same machine as the driver. As -such it would appear as localhost to browsers.
-
-For the .Net driver embedded is very unlikely as Internet Information -Server is running in its own process. For the Java driver, this could -simple be a necessary choice - i.e. the deployment target is WebLogic -or -WebSphere which are not too embeddable. 
-
-In this scenario we suggest you deploy a small web-app alongside the -AUT that will liase between the driver process and the browser. Of -course, there is less fine grained control over the starting and -stopping of the server and indeed the version of the AUT. If the web -server supports it, it is best to copy a fresh version of the AUT to -the underlying directory that the web-app is mapped to. We call the -small web-app the selenese proxy. It does of course slow things down a -fraction.
-
-Selenese-proxy

-
-If you can deploy a copy of the selenese proxy to remote web server, -and configure it to forward requests to your machine, then you can -essentially script that remote web app. The downside of this is that -that remote machine can essentially only be driven from the machine -that is configured to drive it. i.e. it would need to be reconfigured -to be driven from elsewhere. The upside is that you can to a great -extent mix and match your technologies to achieve this proxying (a Java -driver could use a Python selenese-proxy script a web-app).
-

Nearby Web Server
-

-This is where the AUT is running on a nearby testing stack or dedicated -development box (not the developer's own workstation).
-
-To achieve this the selenese proxy needs to be deployed again, this -time to that nearby machine. It will need to be reconfigured to -indicate that selenese traffic is either forwarded to a particular -machine.
-
-

Remote Web Server
-

-This is where the AUT is running on a remote machine, which you have no -control over.  A good example would be www.google.com.  It is -worth pointing out that this is of more interest to hackers or data -harvesters than testing professionals, as what self respecting -development group would prevent you from deploying at least the -Selenese Proxy webapp to a testing stack.
-
-Funnel

-
-We are writing an application called the funnel that can help us -overcome the same -origin issue that is key to Selenium. It essentially makes a -selenium-driver/ directory appear on a remote web site for the purposes -of the browser.
-
-
-
-
- - diff --git a/tests/FunctionalTests/selenium/doc/home-page.html b/tests/FunctionalTests/selenium/doc/home-page.html deleted file mode 100644 index 3806386b..00000000 --- a/tests/FunctionalTests/selenium/doc/home-page.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - Selenium - - - - - -
- News - -
-
September ??, 2005
-
Selenium-0.6 is available - (release notes) - - download now -
-
- -
- -

-Selenium is a test tool for web applications. Selenium tests run -directly in a browsers, just as real users do. And they run in -Internet Explorer, Mozilla and Firefox on Windows, Linux and Macintosh. No -other test tool covers such a wide array of platforms. -

- - -Selenium -uses a unique mechanism which allows it to run on so multiple -platforms. Installed with your application webserver, Selenium -automatically deploys it's JavaScript automation engine -- the Browser -Bot -- to your browser when you point it at the Selenium install point -on your webserver. Thus, you must have write access to the machine your -web application server is running on to install Selenium.
-
-
"Considering the simplicity of it, it is -almost surprising that no one has thought of doing this previously. The -framework is simple and the code is neat and very maintainable. -Sometimes it takes a work of genius to find the uncomplicated solution -to a potentially complicated problem." - Antony Marcano
-
-

-
-
Selenium was -developed by team -of programmers and testers at -ThoughtWorks. It is -open-source software and can -be downloaded and used without charge. It is currently under active -development by our team. Stay tuned for updates and further -announcements.
-
-
-ThoughtWorks is a leader in Agile development methods for enterprise -software development. Selenium is designed specifically for the -acceptance testing requirements of Agile teams. However, teams -using more traditional development will also find it useful.
-

Supported Browsers and Platforms

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-
Internet -Explorer
-
Mozilla
-
Firefox
-
Safari
-
Windows XP
-
6.0
-
1.6+, 1.7+
-
0.8+, 0.9+, 1.0
-

-
Red Hat Linux
-

-
1.6+, 1.7+
-
0.8+, 0.9+, 1.0+
-

-
Mac OS X 10.3
-
not supported
-
1.6+, 1.7+
-
0.8+, 0.9+, 1.0+
-
1.3+
-
-
-
-
-

How does Selenium Work?
-

-Selenium uses JavaScript and Iframes to embed a test automation -engine in your browser. This technique should work with any -JavaScript-enabled browser. Because different browsers handle -JavaScript somewhat differently, we usually have to tweak the engine to -support new browsers. -

Where did Selenium Come From?

-Selenium grew out of a testing framework that was -developed to acceptance-test the functionality of ThoughtWorks' new -web-based time & expense reporting application. It was written by -Jason Huggins, Paul Gross and Jie Tina Wang.
-

Jason -started demoing the test framework for various colleagues. Many were -excited about its immediate and intuitive visual feedback, as well as -its potential to grow as a reusable testing framework for other web -applications.

-And Selenium was born. -
-

Having Trouble?

-Check out our Frequently -Asked Questions page -for more information. - - diff --git a/tests/FunctionalTests/selenium/doc/images/Adjacent.png b/tests/FunctionalTests/selenium/doc/images/Adjacent.png deleted file mode 100644 index 6da4ad66..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/Adjacent.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/Embedded.png b/tests/FunctionalTests/selenium/doc/images/Embedded.png deleted file mode 100644 index 8e5967d7..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/Embedded.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/SmallAdjacent.png b/tests/FunctionalTests/selenium/doc/images/SmallAdjacent.png deleted file mode 100644 index 3cf28aec..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/SmallAdjacent.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/SmallEmbedded.png b/tests/FunctionalTests/selenium/doc/images/SmallEmbedded.png deleted file mode 100644 index 399acbf5..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/SmallEmbedded.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/SmallStandalone.png b/tests/FunctionalTests/selenium/doc/images/SmallStandalone.png deleted file mode 100644 index f04266a0..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/SmallStandalone.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/Standalone.png b/tests/FunctionalTests/selenium/doc/images/Standalone.png deleted file mode 100644 index f9b670c0..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/Standalone.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/localhostAut.png b/tests/FunctionalTests/selenium/doc/images/localhostAut.png deleted file mode 100644 index 25204654..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/localhostAut.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/localhostDriver.png b/tests/FunctionalTests/selenium/doc/images/localhostDriver.png deleted file mode 100644 index a904d7d4..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/localhostDriver.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/localhostSelenium.png b/tests/FunctionalTests/selenium/doc/images/localhostSelenium.png deleted file mode 100644 index af527be5..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/localhostSelenium.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/stockmeister.png b/tests/FunctionalTests/selenium/doc/images/stockmeister.png deleted file mode 100644 index b07aabc6..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/stockmeister.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/images/tested-with-selenium.png b/tests/FunctionalTests/selenium/doc/images/tested-with-selenium.png deleted file mode 100644 index fa80b414..00000000 Binary files a/tests/FunctionalTests/selenium/doc/images/tested-with-selenium.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/doc/index.html b/tests/FunctionalTests/selenium/doc/index.html deleted file mode 100644 index 8f7fed80..00000000 --- a/tests/FunctionalTests/selenium/doc/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - Selenium - - - - - - - - - - diff --git a/tests/FunctionalTests/selenium/doc/jsrmi.html b/tests/FunctionalTests/selenium/doc/jsrmi.html deleted file mode 100644 index 035f4a4e..00000000 --- a/tests/FunctionalTests/selenium/doc/jsrmi.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - JSRMI - - -

JSRMI (Javascript Remote Method Invocation) is a portable browser-neutral Javascript library that makes it possible to execute -Javascript functions in a browser from a process external to the browser.

-

JSRMI is not in any way tied to Java's RMI, but provides a similar mechanism. JSRMI is completely decoupled from the core Selenium Javascript API, but it can -be used to access the Selenium API from outside the browser.

-

All of the -browser-side JSRMI code resides in the rmi.js script - available in the Selenium -distribution.

-

Browser support

- -

Language support

- -

Libraries for other languages are under way.

-

How do I use JSRMI from an external process?

-

Ruby

-

Just include the jsrmi script in your own:

-

require "jsrmi"
-
-browser = Selenium::Browser.new.proxy
-someArea = browser.document.getElementById("someArea")
-someArea.value = "Hello from Ruby #{Time.new}"

-

This will modify the text of a text area in the browser. Looks strangely -familiar to Javascript doesn't it? You can of course call the selenium API too -if the browser has loaded the main Selenium page (which also includes the rmi.js -script - at least that is the plan - I hope (Aslak)).

-

How does it work?

-

(You can safely skip this section if you don't care - this is gory details)

-

Browser side

-

The rmi.js script uses the - -XMLHttpRequest object (available in all compatible browsers) to communicate -with the external process. It executes a GET-POST loop which is repeated ad -infinitum - pulling JSRMI invocations from the external process with GET and -POSTing the results back. This all happens in a separate thread, thereby having -minimal impact on the rest of the web page - without causing a page refresh.

-

The rmi.js script will do a HTTP GET to a URL on the same host/port as the rmi.js -script was loaded from. The content returned from the GET (which must comply -with the JSRMI protocol) is then translated into -Javascript and dynamically executed via Javascript's -eval() function.

-

The result of the function call (typically a Javascript object) is translated -back into the JSRMI protocol format and POSTed back to the same URL as the GET.

-

External process side

-

The external process typically consists of a library that embeds the -following functionality:

- -

A local invocation should translate the invocation to a JSRMI protocol string -and put it on the output queue (which jsrmi will GET). It should then wait for -the result of the browser side invocation to be put back on the input queue via -a POST from jsrmi. Finally it should translate the return value (another JSRMI -protocol string) into a native object and return it to the caller.

-

At any given point in time there should only be one single JSRMI protocol -string in one of the queues - depending on the where the invocation is in its -lifecycle.

-

Reference objects

-

JSRMI allows objects (such as browser side HTMLDocument, HTMLTextField etc) -to be transferred back and forth. This is based on a simple mechanism where each -object is given a unique id and maintained in a pool on each side. this pool is -used to reference and dereference native objects back and forth from the JSRMI -protocol strings.

-

Why would I use JSRMI?

-

With Selenium

-

The Selenium browser runtime will load both selenium test scripts and the web -pages from the web application you're testing into the browser. Modern browsers -don't allow content to be loaded from different hosts (cross browsing security -restrictions). A web application being tested will typically be deployed on a -server, and therefore the selenium test scripts must be loaded from the same web -server. Depending on who's writing the Selenium scripts and executing them, this -may or may not be a restriction to its usage.

-

Under some circumstances it is desirable to keep Selenium test scripts on -your local machine (the same as the one running the browser with the Selenium -runtime) rather than on a remote web server hosting the web application being -tested. Some examples are:

- -

It is important to emphasise that hosting the Selenium scripts on a local -machine would also require that the browser loads the web site being tested from -the local machine. Aren't we creating new problems by requiring testers to -install a full web server environment on their machines? Actually no. The JSRMI -libraries in Ruby and Java (and those who may follow) will soon provide a light -HTTP proxy server. The local browser will load the remote web site through this -HTTP proxy. The browser's security restrictions are satisfied since all content -(Selenium runtime, Selenium scripts and the remote website) is loaded through -localhost.

-

Scripting of existing web applications

-

Think of all boring web form tasks you could automate with JSRMI....

-

The JSRMI protocol

-

TODO: describe the format.

-

How do I implement a JSRMI client library for language X?

-

Start by understand the inner workings - look at the ruby implementation and -study the javascript. (When the JSRMI protocol is better described, studying -this code should not be necessary).

-

It will be to implement a JSRMI client -library in a dynamic language than a static language, because dynamic languages -allow arbitrary messages (method invocations) to be sent to an object. Most -dynamic languages (Ruby, Python, Groovy, Smalltalk) have a generic mechanism to -intercept any message and an object message->JSRMI protocol translation logic is -trivial to implement based on this.

-

Guidelines for static languages such as Java and C#

-

JSRMI clients for static languages such as Java or C# will either have to -choose a subset of the Javascript functions and objects that you want to access, -or implement some generic invocation mechanism that allows raw JSRMI protocol -strings.

-

The former is more easy to use from a user perspective, but will be -restricted in terms of flexibility. The latter is completely generic, but -awkward to deal with from a user perspective.

-

The recommendation is to implement a raw interface to the JSRMI protocol and -have a generic dynamic proxy implementation on top of that. This way the API -support can easily be extended simply by implementing new interfaces for the -Javascript counterparts and generate dynamic proxies on the fly as needed.

-

Calling functions/methods in an external process from the browser using JSRMI

-

This is currently not possible.

- - \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/doc/release-notes.html b/tests/FunctionalTests/selenium/doc/release-notes.html deleted file mode 100644 index f7b7971b..00000000 --- a/tests/FunctionalTests/selenium/doc/release-notes.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - Release Notes - - - - - -Release information for different distributions of Selenium - -

Selenium 0.6.0

- -September 24, 2005 - -
-
pattern-matching
Support for regular-expression and exact matching. Allow patterns to be used to match alert and confirmation messages.
-
support for Javascript prompts
Capture and verify prompt-messages, set up return values.
-
fireEvent command
Allows arbitrary events to be raised.
-
logging
New "pop up" log window.
- -
error-handling
Better handling and reporting of internal errors.
-
bug-fixes
Various defects fixed.
-
- -

-See also: JIRA release-summary. -

- -

Selenium 0.5.0

- -June 19, 2005 - -
-
"waitForValue" command
Tells Selenium to wait until an input element has a specified value.
-
"close" command
Closes an open popup window
-
DOM Viewer
Now works in IE, show/hide works in all browsers
-
Option locators
Can now select options based on index, value or id, as well as label
-
verifyLocation
Now handles querystring in the url
-
selectWindow
Can now select windows that aren't assigned to a global variable
-
TestRunner hanging
Fixed problem found in some IE installations
-
- -

-See also: JIRA release-summary. - -

Selenium 0.4.0

- -May 20, 2005 - -

This release breaks backward compatibility in 3 ways: -

    -
  1. The 'click' command now requires the 'AndWait' suffix in order to wait for a page to reload. The 'nowait' parameter is no longer supported.
  2. -
  3. The previously undocumented 'link:' locator is now specified as 'link=the link text'
  4. -
  5. The previously undocumented 'setVariable' command has been renamed to 'store', with slightly different semantics.
  6. -
-

- -
-
Safari support
Most Selenium features now work in Safari!
-
Click command doesn't wait
Use 'clickAndWait' to wait for a page reload
-
Locator specificity
Can use prefixes ('id=', 'xpath=' etc) to specify exactly which locator strategy to use.
-
Better XPath support
Works in Konqueror, and is faster on other platforms.
-
Javascript parameters
All parameters can now take a javascript{...} syntax, constructing the parameter value from javascript.
-
Handle 'AndWait' commands in popup windows
This bug has been fixed
-
Bug fixes
Many broken things fixed.
-
- -

-See also: JIRA release-summary. - -

Selenium 0.3.0

- -May 2, 2005 - - - - -

Selenium 0.2

- -Jan 20, 2005 - - -
-
- - diff --git a/tests/FunctionalTests/selenium/doc/rst2html.bat b/tests/FunctionalTests/selenium/doc/rst2html.bat deleted file mode 100644 index 8fc9043f..00000000 --- a/tests/FunctionalTests/selenium/doc/rst2html.bat +++ /dev/null @@ -1,3 +0,0 @@ -rem - Uses Python docutils-0.3.5 -rem - URL: http://docutils.sourceforge.net -c:/python23/python.exe c:/python23/Scripts/rst2html.py ./seleniumReference.txt ./seleniumReference.html \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/doc/seleniumReference.html b/tests/FunctionalTests/selenium/doc/seleniumReference.html deleted file mode 100644 index b9b186b9..00000000 --- a/tests/FunctionalTests/selenium/doc/seleniumReference.html +++ /dev/null @@ -1,1148 +0,0 @@ - - - - - - -Selenium Reference - - - -

Selenium Reference

-
-
-

A command is what tells Selenium what to do. Selenium commands come in two 'flavors', Actions and Assertions. -Each command call is one line in the test table of the form:

-
- ----- - - - - - - -
commandtargetvalue
-
-

Actions are commands that generally manipulate the state of the application. They do things like "click this link" and "select that option". If an Action fails, or has an error, the execution of the current test is stopped.

-

Checks verify the state of the application conforms to what is expected. Examples include "make sure the page title is X" and "check that this checkbox is checked". It is possible to tell Selenium to stop the test when an Assertion fails, or to simply record the failure and continue.

-

Element Locators tell Selenium which HTML element a command refers to. Many commands require an Element Locator as the "target" attribute. Examples of Element Locators include "elementId" and "document.forms[0].element". These are described more clearly in the next section.

-

Patterns 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.

-
-
-

Element Locators

-
-

Element Locators allow Selenium to identify which HTML element a -command refers to. We support the following strategies for locating -elements:

-
-
id=id
-
Select the element with the specified @id attribute.
-
name=name
-
Select the first element with the specified @name attribute.
-
identifier=id
-
Select the element with the specified @id attribute. If no match is found, select the first element whose @name attribute is id.
-
dom=javascriptExpression
-
-
Find an element using JavaScript traversal of the HTML Document Object Model. DOM locators must begin with "document.".
-
    -
  • dom=document.forms['myForm'].myDropdown
  • -
  • dom=document.images[56]
  • -
-
-
-
-
xpath=xpathExpression
-
-
Locate an element using an XPath expression. XPath locators must begin with "//".
-
    -
  • xpath=//img[@alt='The image alt text']
  • -
  • xpath=//table[@id='table1']//tr[4]/td[2]
  • -
-
-
-
-
link=textPattern
-
-
Select the link (anchor) element which contains text matching the specified pattern.
-
    -
  • link=The link text
  • -
-
-
-
-
-

Without a locator prefix, Selenium uses:

-
    -
  • dom, for locators starting with "document."
  • -
  • xpath, for locators starting with "//"
  • -
  • identifier, otherwise
  • -
-
-
-
-

Select Option Specifiers

-
-

Select Option Specifiers provide different ways of specifying options of an HTML Select element (e.g. for selecting a specific option, or for asserting that the selected option satisfies a specification). There are several forms of Select Option Specifier.

-
-
label=labelPattern
-
-
matches options based on their labels, i.e. the visible text.
-
    -
  • label=regexp:^[Oo]ther
  • -
-
-
-
-
value=valuePattern
-
-
matches options based on their values.
-
    -
  • value=other
  • -
-
-
-
-
id=id
-
-
matches options based on their ids.
-
    -
  • id=option1
  • -
-
-
-
-
index=index
-
-
matches an option based on its index (offset from zero).
-
    -
  • index=2
  • -
-
-
-
-
-

Without a prefix, the default behaviour is to only match on labels.

-
-
-
-

String-match Patterns

-
-

Various Pattern syntaxes are available for matching string values:

-
-
glob:pattern
-
Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a kind of limited regular-expression syntax typically used in command-line shells. In a glob pattern, "*" represents any sequence of characters, and "?" represents any single character. Glob patterns match against the entire string.
-
regexp:regexp
-
Match a string using a regular-expression. The full power of JavaScript regular-expressions is available.
-
exact:string
-
Match a string exactly, verbatim, without any of that fancy wildcard stuff.
-
-

If no pattern prefix is specified, Selenium assumes that it's a "glob" pattern.

-
-
-
-

Selenium Actions

-
-

Actions tell Selenium to do something in the application. They generally represent something a user would do.

-

Many Actions can be called with the "AndWait" suffix. This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load. -The exceptions to this pattern are the "open" and "click" actions, which will both wait for a page to load by default.

-

open( url )

-
-

Opens a URL in the test frame. This accepts both relative and absolute URLs.

-

Note: The URL must be on the same site as Selenium due to security restrictions in the browser (Cross Site Scripting).

-

examples:

-
- ----- - - - - - - - - - - -
open/mypage 
openhttp://localhost/ 
-
-
-

click( elementLocator )

-
-

Clicks on a link, button, checkbox or radio button. -If the click action causes a new page to load (like a link usually does), use "clickAndWait".

-

examples:

-
- ----- - - - - - - - - - - - - - - -
clickaCheckbox 
clickAndWaitsubmitButton 
clickAndWaitanyLink 
-
-
-
note:
-
Selenium will always automatically click on a popup dialog raised by the alert() or confirm() -methods. (The exception is those raised during 'onload', which are not yet handled by Selenium). -You must use [verify|assert]Alert or [verify|assert]Confirmation to tell Selenium that you expect the -popup dialog. You may use chooseCancelOnNextConfirmation to click 'cancel' on the next confirmation -dialog instead of clicking 'OK'.
-
-
-

type( inputLocator, value )

-
-

Sets the value of an input field, as though you typed it in.

-

Can also be used to set the value of combo boxes, check boxes, etc. In these cases, value should be the value of the option selected, not the visible text.

-

examples:

-
- ----- - - - - - - - - - - -
typenameFieldJohn Smith
typeAndWaittextBoxThatSubmitsOnChangenewValue
-
-
-

select( dropDownLocator, optionSpecifier )

-
-

Select an option from a drop-down, based on the optionSpecifier. If more than one option matches the specifier (e.g. due to the use of globs like "f*b*", or due to more than one option having the same label or value), then the first matches is selected.

-

examples:

-
- ----- - - - - - - - - - - - - - - - - - - -
selectdropDownAustralian Dollars
selectdropDownindex=0
selectAndWaitcurrencySelectorvalue=AUD
selectAndWaitcurrencySelectorlabel=Aus*lian D*rs
-
-
-

selectWindow( windowId )

-
-

Selects a popup window. Once a popup window has been selected, all commands go to that window. To select the main window again, use "null" as the target.

-

target: The id of the window to select.

-

value: ignored

-

examples:

-
- ----- - - - - - - - - - - -
selectWindowmyPopupWindow 
selectWindownull 
-
-
-

goBack()

-
-

Simulates the user clicking the "back" button on their browser.

-

examples:

-
- ----- - - - - - - -
goBack  
-
-
-

close()

-
-

Simulates the user clicking the "close" button in the titlebar of a popup window.

-

examples:

-
- ----- - - - - - - -
close  
-
-
-

pause( milliseconds )

-
-

Pauses the execution of the test script for a specified amount of time. This is useful for debugging a script or pausing to wait for some server side action.

-

examples:

-
- ----- - - - - - - - - - - -
pause5000 
pause2000 
-
-
-

fireEvent( elementLocator, eventName )

-
-

Explicitly simulate an event, to trigger the corresponding "onevent" handler.

-

examples:

-
- ----- - - - - - - - - - - -
fireEventtextFieldfocus
fireEventdropDownblur
-
-
-

waitForValue( inputLocator, value )

-
-

Waits for a specified input (e.g. a hidden field) to have a specified value. Will succeed immediately if the input already has the value. This is implemented by polling for the value. Warning: can block indefinitely if the input never has the specified value.

-

example:

-
- ----- - - - - - - -
waitForValuefinishIndicationisfinished
-
-
-

store( valueToStore, variableName )

-
-

Stores a value into a variable. The value can be constructed using either variable substitution or javascript evaluation, as detailed in 'Parameter construction and Variables' (below).

-

examples:

-
- ----- - - - - - - - - - - - - - - -
storeMr John Smithfullname
store${title} ${firstname} ${surname}fullname
storejavascript{Math.round(Math.PI * 100) / 100}PI
-
-
-

storeValue( inputLocator, variableName )

-
-

Stores the value of an input field into a variable.

-

examples:

-
- ----- - - - - - - - - - - -
storeValueuserNameuserID
typeuserName${userID}
-
-
-

storeText( elementLocator, variableName )

-
-

Stores the text of an element into a variable.

-

examples:

-
- ----- - - - - - - - - - - -
storeTextcurrentDateexpectedStartDate
verifyValuestartDate${expectedStartDate}
-
-
-

storeAttribute( elementLocator@attributeName, variableName )

-
-

Stores the value of an element attribute into a variable.

-

examples:

-
- ----- - - - - - - - - - - -
storeAttributeinput1@classclassOfInput1
verifyAttributeinput2@class${classOfInput1}
-
-
-

chooseCancelOnNextConfirmation()

-
-

Instructs Selenium to click Cancel on the next javascript confirmation dialog to be raised. By default, the confirm function will return true, having the same effect as manually clicking OK. After running this command, the next confirmation will behave as if the user had clicked Cancel.

-

examples:

-
- ----- - - - - - - -
chooseCancelOnNextConfirmation  
-
-
-

answerOnNextPrompt( answerString )

-
-

Instructs Selenium to return the specified answerString in response to the next prompt.

-

examples:

-
- ----- - - - - - - -
answerOnNextPromptKangaroo 
-
-
-
-
-
-

Selenium Checks

-
-

Checks are used to verify the state of the application. They can be used to check the value of a form field, the presense of some text, or the URL of the current page.

-

All Selenium Checks can be used in 2 modes, "assert" and "verify". These behave identically, except that when an "assert" check fails, the test is aborted. When a "verify" check fails, the test will continue execution. -This allows a single "assert" to ensure that the application is on the correct page, followed by a bunch of "verify" checks to test form field values, labels, etc.

-

assertLocation( relativeLocation )

-
-

examples:

-
- ----- - - - - - - - - - - -
verifyLocation/mypage 
assertLocation/mypage 
-
-
-

assertTitle( titlePattern )

-
-

Verifies the title of the current page.

-

examples:

-
- ----- - - - - - - - - - - -
verifyTitleMy Page 
assertTitleMy Page 
-
-
-

assertValue( inputLocator, valuePattern )

-
-

Verifies the value of an input field (or anything else with a value parameter). For checkbox/radio elements, the value will be "on" or "off" depending on whether the element is checked or not.

-

examples:

-
- ----- - - - - - - - - - - -
verifyValuenameFieldJohn Smith
assertValuedocument.forms[2].nameFieldJohn Smith
-
-
-

assertSelected( selectLocator, optionSpecifier )

-
-

Verifies that the selected option of a drop-down satisfies the optionSpecifier.

-

examples:

-
- ----- - - - - - - - - - - - - - - - - - - -
verifySelecteddropdown2John Smith
verifySelecteddropdown2value=js*123
assertSelecteddocument.forms[2].dropDownlabel=J* Smith
assertSelecteddocument.forms[2].dropDownindex=0
-
-
-

assertSelectOptions( selectLocator, optionLabelList )

-
-

Verifies the labels of all options in a drop-down against a comma-separated list. Commas in an expected option can be escaped as ",".

-

examples:

-
- ----- - - - - - - - - - - -
verifySelectOptionsdropdown2John Smith,Dave Bird
assertSelectOptionsdocument.forms[2].dropDownSmith\, J,Bird\, D
-
-
-

assertText( elementLocator, textPattern )

-
-

Verifies the text of an element. This works for any element that contains text. This command uses either the textContent (Mozilla-like browsers) or the innerText (IE-like browsers) of the element, which is the rendered text shown to the user.

-

examples:

-
- ----- - - - - - - - - - - -
verifyTextstatusMessageSuccessful
assertText//div[@id='foo']//h1Successful
-
-
-

assertAttribute( elementLocator@attributeName, valuePattern )

-
-

Verifies the value of an element attribute.

-

examples:

-
- ----- - - - - - - - - - - - - - - -
verifyAttributetxt1@classbigAndBold
assertAttributedocument.images[0]@altalt-text
verifyAttribute//img[@id='foo']/@altalt-text
-
-
-

assertTextPresent( text )

-
-

Verifies that the specified text appears somewhere on the rendered page shown to the user.

-

examples:

-
- ----- - - - - - - - - - - -
verifyTextPresentYou are now logged in. 
assertTextPresentYou are now logged in. 
-
-
-

assertTextNotPresent( text )

-
-Verifies that the specified text does NOT appear anywhere on the rendered page.
-

assertElementPresent( elementLocator )

-
-

Verifies that the specified element is somewhere on the page.

-

examples:

-
- ----- - - - - - - - - - - -
verifyElementPresentsubmitButton 
assertElementPresent//img[@alt='foo'] 
-
-
-

assertElementNotPresent( elementLocator )

-
-

Verifies that the specified element is NOT on the page.

-

examples:

-
- ----- - - - - - - - - - - -
verifyElementNotPresentcancelButton 
assertElementNotPresentcancelButton 
-
-
-

assertTable( cellAddress, valuePattern )

-
-

Verifies the text in a cell of a table. The cellAddress syntax tableName.row.column, where row and column start at 0.

-

examples:

-
- ----- - - - - - - - - - - -
verifyTablemyTable.1.6Submitted
assertTableresults.0.213
-
-
-

assertVisible( elementLocator )

-
-

Verifies that the specified element is both present and visible. An element can be rendered invisible by setting the CSS "visibility" property to "hidden", or the "display" property to "none", either for the element itself or one if its ancestors.

-

examples:

-
- ----- - - - - - - - - - - -
verifyVisiblepostcode 
assertVisiblepostcode 
-
-
-

assertNotVisible( elementLocator )

-
-

Verifies that the specified element is NOT visible. Elements that are simply not present are also considered invisible.

-

examples:

-
- ----- - - - - - - - - - - -
verifyNotVisiblepostcode 
assertNotVisiblepostcode 
-
-
-

verifyEditable / assertEditable( inputLocator )

-
-

Verifies that the specified element is editable, ie. it's an input element, and hasn't been disabled.

-

examples:

-
- ----- - - - - - - - - - - -
verifyEditableshape 
assertEditablecolour 
-
-
-

assertNotEditable( inputLocator )

-
-Verifies that the specified element is NOT editable, ie. it's NOT an input element, or has been disabled.
-

assertAlert( messagePattern )

-
-

Verifies that a javascript alert with the specified message was generated. Alerts must be verified in the same order that they were generated.

-

Verifying an alert has the same effect as manually clicking OK. If an alert is generated but you do not verify it, the next Selenium action will fail.

-

NOTE: under Selenium, javascript alerts will NOT pop up a visible alert dialog.

-

NOTE: Selenium does NOT support javascript alerts that are generated in a page's onload() event handler. In this case a visible dialog WILL be generated and Selenium will hang until you manually click OK.

-

examples:

-
- ----- - - - - - - - - - - -
verifyAlertInvalid Phone Number 
assertAlertInvalid Phone Number 
-
-
-

assertConfirmation( messagePattern )

-
-

Verifies that a javascript confirmation dialog with the specified message was generated. Like alerts, confirmations must be verified in the same order that they were generated.

-

By default, the confirm function will return true, having the same effect as manually clicking OK. This can be changed by prior execution of the chooseCancelOnNextConfirmation command (see above). If an confirmation is generated but you do not verify it, the next Selenium action will fail.

-

NOTE: under Selenium, javascript confirmations will NOT pop up a visible dialog.

-

NOTE: Selenium does NOT support javascript confirmations that are generated in a page's onload() event handler. In this case a visible dialog WILL be generated and Selenium will hang until you manually click OK.

-

examples:

-
- ----- - - - - - - - - - - -
assertConfirmationRemove this user? 
verifyConfirmationAre you sure? 
-
-
-

assertPrompt( messagePattern )

-
-

Verifies that a javascript prompt dialog with the specified message was generated. Like alerts, prompts must be verified in the same order that they were generated.

-

Successful handling of the prompt requires prior execution of the answerOnNextPrompt command (see above). If a prompt is generated but you do not verify it, the next Selenium action will fail.

-

examples:

-
- ----- - - - - - - - - - - - - - - -
answerOnNextPromptJoe 
clickid=delegate 
verifyPromptDelegate to who? 
-
-
-
-
-
-

Parameter construction and Variables

-
-

All Selenium command parameters can be constructed using both simple -variable substitution as well as full javascript. Both of these -mechanisms can access previously stored variables, but do so using -different syntax.

-

Stored Variables

-

The commands store, storeValue and storeText can be used to store a variable -value for later access. Internally, these variables are stored in a map called "storedVars", -with values keyed by the variable name. These commands are documented in the command reference.

-

Variable substitution

-

Variable substitution provides a simple way to include a previously stored variable in a -command parameter. This is a simple mechanism, by which the variable to substitute is indicated -by ${variableName}. Multiple variables can be substituted, and intermixed with static text.

-

Example:

-
- ----- - - - - - - - - - - - - - - - - - - -
storeMrtitle
storeValuenameFieldsurname
store${title} ${surname}fullname
typetextElementFull name is: ${fullname}
-
-

Javascript evaluation

-

Javascript evaluation provides the full power of javascript in constructing a command parameter. -To use this mechanism, the entire parameter value must be prefixed by -'javascript{' with a trailing '}'. The text inside the braces is evaluated as a javascript expression, -and can access previously stored variables using the storedVars map detailed above. -Note that variable substitution cannot be combined with javascript evaluation.

-

Example:

-
- ----- - - - - - - - - - - -
storejavascript{'merchant' + (new Date()).getTime()}merchantId
typetextElementjavascript{storedVars['merchantId'].toUpperCase()}
-
-
-
-
-

Extending Selenium

-
-

It can be quite simple to extend Selenium, adding your own actions, checks and locator-strategies. -This is done with javascript by adding methods to the Selenium object prototype, and the PageBot -object prototype. On startup, Selenium will automatically look through methods on these prototypes, -using name patterns to recognise which ones are actions, checks and locators.

-

The following examples try to give an indication of how Selenium can be extended with javascript.

-
-

Actions

-
-

All doFoo methods on the Selenium prototype are added as actions. For each action foo there -is also an action fooAndWait registered. An action method can take up to 2 parameters, which -will be passed the second and third column values in the test.

-

Example: Add a "typeRepeated" action to Selenium, which types the text twice into a text box.

-
-Selenium.prototype.doTypeRepeated = function(locator, text) {
-    // All locator-strategies are automatically handled by "findElement"
-    var element = this.page().findElement(locator);
-
-    // Create the text to type
-    var valueToType = text + text;
-
-    // Replace the element text with the new text
-    this.page().replaceText(element, valueToType);
-};
-
-
-

Checks

-
-

All assertFoo methods on the Selenium prototype are added as checks. For each check foo there -is an assertFoo and verifyFoo registered. An assert method can take up to 2 parameters, which -will be passed the second and third column values in the test.

-

Example: Add a valueRepeated check, that makes sure that the element value -consists of the supplied text repeated. The 2 commands that would be available in tests would be -assertValueRepeated and verifyValueRepeated.

-
-Selenium.prototype.assertValueRepeated = function(locator, text) {
-    // All locator-strategies are automatically handled by "findElement"
-    var element = this.page().findElement(locator);
-
-    // Create the text to verify
-    var expectedValue = text + text;
-
-    // Get the actual element value
-    var actualValue = element.value;
-
-    // Make sure the actual value matches the expected
-    this.assertMatches(expectedValue, actualValue);
-};
-
-
-

Locator Strategies

-
-

All locateElementByFoo 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.

-

Example: Add a "valuerepeated=" locator, that finds the first element a value attribute equal to the the supplied value repeated.

-
-// The "inDocument" is a the document you are searching.
-PageBot.prototype.locateElementByValueRepeated = function(text, inDocument) {
-    // Create the text to search for
-    var expectedValue = text + text;
-
-    // Loop through all elements, looking for ones that have 
-    // a value === our expected value
-    var allElements = inDocument.getElementsByTagName("*");
-    for (var i = 0; i < allElements.length; i++) {
-        var testElement = allElements[i];
-        if (testElement.value && testElement.value === expectedValue) {
-            return testElement;
-        }
-    }
-    return null;
-};
-
-
-

user-extensions.js

-
-

By default, Selenium looks for a file called "user-extensions.js", 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.

-

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.

-
-
-

:

-
-
- - diff --git a/tests/FunctionalTests/selenium/doc/seleniumReference.txt b/tests/FunctionalTests/selenium/doc/seleniumReference.txt deleted file mode 100644 index e7819869..00000000 --- a/tests/FunctionalTests/selenium/doc/seleniumReference.txt +++ /dev/null @@ -1,771 +0,0 @@ -========================= -Selenium Reference -========================= - --------- -Concepts --------- - - A **command** is what tells Selenium what to do. Selenium commands come in two 'flavors', **Actions** and **Assertions**. - Each command call is one line in the test table of the form: - - ======= ====== ===== - command target value - ======= ====== ===== - - **Actions** are commands that generally manipulate the state of the application. They do things like "click this link" and "select that option". If an Action fails, or has an error, the execution of the current test is stopped. - - **Assertions** verify the state of the application conforms to what is expected. Examples include "make sure the page title is X" and "verify that this checkbox is checked". It is possible to tell Selenium to stop the test when an Assertion fails, or to simply record the failure and continue. - - **Element Locators** tell Selenium which HTML element a command refers to. Many commands require an Element Locator as the "target" attribute. Examples of Element Locators include "elementId" and "document.forms[0].element". These are described more clearly in the next section. - - **Patterns** 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. - ------------------ -Element Locators ------------------ - - Element Locators allow Selenium to identify which HTML element a - command refers to. The format of a locator is: - - *locatorType*\ **=**\ *argument* - - We support the following strategies for locating - elements: - - **id=**\ *id* - - Select the element with the specified @id attribute. - - **name=**\ *name* - - Select the first element with the specified @name attribute. - - username - - name=username - - The name may optionally be following by one or more *element-filters*, separated from the name by whitespace. If the *filterType* is not specified, **value** is assumed. - - name=flavour value=chocolate - - **identifier=**\ *id* - - Select the element with the specified @id attribute. If no match is found, select the first element whose @name attribute is *id*. - - **dom=**\ *javascriptExpression* - - Find an element using JavaScript traversal of the HTML Document Object Model. DOM locators *must* begin with "document.". - - dom=document.forms['myForm'].myDropdown - - dom=document.images[56] - - **xpath=**\ *xpathExpression* - - Locate an element using an XPath expression. - - xpath=//img[@alt='The image alt text'] - - xpath=//table[@id='table1']//tr[4]/td[2] - - **link=**\ *textPattern* - - Select the link (anchor) element which contains text matching the specified *pattern*. - - link=The link text - - - If no *locatorType* is specified, Selenium uses: - - * **dom**, for locators starting with "document." - * **xpath**, for locators starting with "//" - * **identifier**, otherwise - ---------------- -Element Filters ---------------- - - Element filters can be used with a locator to refine a list of candidate elements. They are currently used only in the 'name' element-locator. - - Filters look much like locators, ie. - - *filterType*\ **=**\ *argument* - - Supported element-filters are: - - **value=**\ *valuePattern* - - Matches elements based on their values. This is particularly useful for refining a list of similarly-named toggle-buttons. - - **index=**\ *index* - - Selects a single element based on its position in the list offset from zero). - ------------------------- -Select Option Specifiers ------------------------- - - Select Option Specifiers provide different ways of specifying options of an HTML Select element (e.g. for selecting a specific option, or for asserting that the selected option satisfies a specification). There are several forms of Select Option Specifier. - - **label=**\ *labelPattern* - matches options based on their labels, i.e. the visible text. - - label=regexp:^[Oo]ther - - **value=**\ *valuePattern* - matches options based on their values. - - value=other - - **id=**\ *id* - matches options based on their ids. - - id=option1 - - **index=**\ *index* - matches an option based on its index (offset from zero). - - index=2 - - If no optionSpecifierType prefix is provided, the default behaviour is to match on **label**. - ------------------------- -String-match Patterns ------------------------- - - Various Pattern syntaxes are available for matching string values: - - **glob:**\ *pattern* - Match a string against a "glob" (aka "wildmat") pattern. "Glob" is a kind of limited regular-expression syntax typically used in command-line shells. In a glob pattern, "*" represents any sequence of characters, and "?" represents any single character. Glob patterns match against the entire string. - - **regexp:**\ *regexp* - Match a string using a regular-expression. The full power of JavaScript regular-expressions is available. - - **exact:**\ *string* - Match a string exactly, verbatim, without any of that fancy wildcard stuff. - - If no pattern prefix is specified, Selenium assumes that it's a "glob" pattern. - ----------------- -Selenium Actions ----------------- - - Actions tell Selenium to do something in the application. They generally represent something a user would do. - - Many **Actions** can be called with the "AndWait" suffix. This suffix tells Selenium that the action will cause the browser to make a call to the server, and that Selenium should wait for a new page to load. - - **open**\ ( *url* ) - - Opens a URL in the test frame. This accepts both relative and absolute URLs. - - The "open" command waits for the page to load before proceeding, - ie. the "AndWait" suffix is implicit. - - *Note*: The URL must be on the same site as Selenium due to security restrictions in the browser (Cross Site Scripting). - - **examples:** - - ==== ================= ===== - open /mypage - open http://localhost/ - ==== ================= ===== - - **click**\ ( *elementLocator* ) - - Clicks on a link, button, checkbox or radio button. - If the click action causes a new page to load (like a link usually does), use "clickAndWait". - - **examples:** - - ============ ================== ===== - click aCheckbox - clickAndWait submitButton - clickAndWait anyLink - ============ ================== ===== - - **type**\ ( *inputLocator*, *value* ) - - Sets the *value* of an input field, as though you typed it in. - - Can also be used to set the value of combo boxes, check boxes, etc. In these cases, *value* should be the value of the option selected, not the visible text. - - **examples:** - - =========== ========================== ========== - type nameField John Smith - typeAndWait textBoxThatSubmitsOnChange newValue - =========== ========================== ========== - - **select**\ ( *dropDownLocator*, *optionSpecifier* ) - - Select an option from a drop-down, based on the *optionSpecifier*. If more than one option matches the specifier (e.g. due to the use of globs like "f*b*", or due to more than one option having the same label or value), then the first matches is selected. - - **examples:** - - ============= ================ ========== - select dropDown Australian Dollars - select dropDown index=0 - selectAndWait currencySelector value=AUD - selectAndWait currencySelector label=Aus*lian D*rs - ============= ================ ========== - - **check**\ ( *toggleButtonLocator* ) - - Check a toggle-button (ie. a check-box or radio-button). - - Note: if addressing the toggle-button element by name, you'll need to append an element-filter (e.g. typically by value), since toggle-button groups consist of input-elements with the same name. - - **examples:** - - ============= ======================== ========== - check name=flavour value=honey - check flavour honey - ============= ======================== ========== - - **uncheck**\ ( *toggleButtonLocator* ) - - Un-check a toggle-button. - - **selectWindow**\ ( *windowId* ) - - Selects a popup window. Once a popup window has been selected, all commands go to that window. To select the main window again, use "null" as the target. - - **target:** The id of the window to select. - - **value:** *ignored* - - **examples:** - - ============ ============= ===== - selectWindow myPopupWindow - selectWindow null - ============ ============= ===== - - **goBack**\ () - - Simulates the user clicking the "back" button on their browser. - - **examples:** - - ============= ==== ===== - goBackAndWait - ============= ==== ===== - - **close**\ () - - Simulates the user clicking the "close" button in the titlebar of a popup window. - - **examples:** - - ====== ==== ===== - close - ====== ==== ===== - - **pause**\ ( *milliseconds* ) - - Pauses the execution of the test script for a specified amount of time. This is useful for debugging a script or pausing to wait for some server side action. - - **examples:** - - ===== ==== ===== - pause 5000 - pause 2000 - ===== ==== ===== - - **fireEvent**\ ( *elementLocator*, *eventName* ) - - Explicitly simulate an event, to trigger the corresponding "on\ *event*" handler. - - **examples:** - - ========= =========== ======== - fireEvent textField focus - fireEvent dropDown blur - ========= =========== ======== - - **waitForValue**\ ( *inputLocator*, *value* ) - - Waits for a specified input (e.g. a hidden field) to have a specified *value*. Will succeed immediately if the input already has the value. This is implemented by polling for the value. Warning: can block indefinitely if the input never has the specified value. - - **example:** - - ============ ================ ========== - waitForValue finishIndication isfinished - ============ ================ ========== - - **store**\ ( *valueToStore*, *variableName* ) - - Stores a value into a variable. The value can be constructed using either variable substitution or JavaScript evaluation, as detailed in 'Parameter construction and Variables' (below). - - **examples:** - - ========== ============================================ ========= - store Mr John Smith fullname - store ${title} ${firstname} ${surname} fullname - store javascript{Math.round(Math.PI * 100) / 100} PI - ========== ============================================ ========= - - **storeValue**\ ( *inputLocator*, *variableName* ) - - Stores the value of an input field into a variable. - - **examples:** - - ========== ========= ========= - storeValue userName userID - type userName ${userID} - ========== ========= ========= - - **storeText**\ ( *elementLocator*, *variableName* ) - - Stores the text of an element into a variable. - - **examples:** - - =========== =========== ==================== - storeText currentDate expectedStartDate - verifyValue startDate ${expectedStartDate} - =========== =========== ==================== - - **storeAttribute**\ ( *elementLocator*\ @\ *attributeName*, *variableName* ) - - Stores the value of an element attribute into a variable. - - **examples:** - - =============== ============== ==================== - storeAttribute input1@\ class classOfInput1 - verifyAttribute input2@\ class ${classOfInput1} - =============== ============== ==================== - - **chooseCancelOnNextConfirmation**\ () - - By default, Selenium's overridden window.confirm() function will - return true, as if the user had manually clicked OK. After running - this command, the next call to confirm() will return false, as if - the user had clicked Cancel. - - **examples:** - - ============================== ===== ===== - chooseCancelOnNextConfirmation - ============================== ===== ===== - - **answerOnNextPrompt**\ ( *answerString* ) - - Instructs Selenium to return the specified *answerString* in - response to the next call to window.prompt(). - - **examples:** - - ========================== ========= ===== - answerOnNextPrompt Kangaroo - ========================== ========= ===== - -------------------- -Selenium Assertions -------------------- - - Assertions are used to verify the state of the application. They can be used to check the value of a form field, the presense of some text, or the URL of the current page. - - All Selenium assertions can be used in 2 modes, "assert" and "verify". These behave identically, except that when an "assert" fails, the test is aborted. When a "verify" fails, the test will continue execution. This allows a single "assert" to ensure that the application is on the correct page, followed by a bunch of "verify" assertions to test form field values, labels, etc. - - A growing number of assertions have a negative version. In most cases, except where indicated, if the positive assertion is of the form **assertXYZ**, then the negative cases will be of the form **assertNotXYZ**. - - **assertLocation**\ ( *relativeLocation* ) - - **examples:** - - ============== ======= ===== - verifyLocation /mypage - assertLocation /mypage - ============== ======= ===== - - **assertTitle**\ ( *titlePattern* ) - - Verifies the title of the current page. - - **examples:** - - =========== ======= ===== - verifyTitle My Page - assertTitle My Page - =========== ======= ===== - - **assertNotTitle**\ ( *titlePattern* ) - - Verifies that the title of the current page does not match the specified pattern. - - **assertValue**\ ( *inputLocator*, *valuePattern* ) - - Verifies the value of an input field (or anything else with a value parameter). For checkbox/radio elements, the value will be "on" or "off" depending on whether the element is checked or not. - - **examples:** - - =========== =========================== ========== - verifyValue nameField John Smith - assertValue document.forms[2].nameField John Smith - =========== =========================== ========== - - **assertNotValue**\ ( *inputLocator*, *valuePattern* ) - - Verifies the value of an input field does not match the specified pattern. - - **assertSelected**\ ( *selectLocator*, *optionSpecifier* ) - - Verifies that the selected option of a drop-down satisfies the *optionSpecifier*. - - **examples:** - - ============== =========================== ========== - verifySelected dropdown2 John Smith - verifySelected dropdown2 value=js*123 - assertSelected document.forms[2].dropDown label=J* Smith - assertSelected document.forms[2].dropDown index=0 - ============== =========================== ========== - - **assertSelectOptions**\ ( *selectLocator*, *optionLabelList* ) - - Verifies the labels of all options in a drop-down against a comma-separated list. Commas in an expected option can be escaped as "\,". - - **examples:** - - =================== =========================== ==================== - verifySelectOptions dropdown2 John Smith,Dave Bird - assertSelectOptions document.forms[2].dropDown Smith\\, J,Bird\\, D - =================== =========================== ==================== - - **assertChecked**\ ( *toggleButtonLocator* ) - - Verifies that the specified toggle-button element is checked. - - **examples:** - - ============= ======================== ========== - verifyChecked flavour honey - ============= ======================== ========== - - **assertText**\ ( *elementLocator*, *textPattern* ) - - Verifies the text of an element. This works for any element that contains text. This command uses either the textContent (Mozilla-like browsers) or the innerText (IE-like browsers) of the element, which is the rendered text shown to the user. - - **examples:** - - ========== ==================== ========== - verifyText statusMessage Successful - assertText //div[@id='foo']//h1 Successful - ========== ==================== ========== - - **assertNotText**\ ( *elementLocator*, *textPattern* ) - - Verifies that the text of an element does not match the specified pattern. - - **assertAttribute**\ ( *elementLocator*\ @\ *attributeName*, *valuePattern* ) - - Verifies the value of an element attribute. - - **examples:** - - =============== ====================== ========== - verifyAttribute txt1@\ class bigAndBold - assertAttribute document.images[0]@alt alt-text - verifyAttribute //img[@id='foo']/@alt alt-text - =============== ====================== ========== - - **assertNotAttribute**\ ( *elementLocator*\ @\ *attributeName*, *valuePattern* ) - - Verifies that the value of an element attribute does not match the specified pattern. - - **assertTextPresent**\ ( *text* ) - - Verifies that the specified text appears somewhere on the rendered page shown to the user. - - **examples:** - - ================= ====================== ===== - verifyTextPresent You are now logged in. - assertTextPresent You are now logged in. - ================= ====================== ===== - - **assertTextNotPresent**\ ( *text* ) - - Verifies that the specified text does NOT appear anywhere on the rendered page. - - **assertElementPresent**\ ( *elementLocator* ) - - Verifies that the specified element is somewhere on the page. - - **examples:** - - ==================== ================= ===== - verifyElementPresent submitButton - assertElementPresent //img[@alt='foo'] - ==================== ================= ===== - - **assertElementNotPresent**\ ( *elementLocator* ) - - Verifies that the specified element is NOT on the page. - - **examples:** - - ======================= ============ ===== - verifyElementNotPresent cancelButton - assertElementNotPresent cancelButton - ======================= ============ ===== - - **assertTable**\( *cellAddress*, *valuePattern* ) - - Verifies the text in a cell of a table. The *cellAddress* syntax *tableName.row.column*, where row and column start at 0. - - **examples:** - - =========== =========== ========= - verifyTable myTable.1.6 Submitted - assertTable results.0.2 13 - =========== =========== ========= - - **assertNotTable**\( *cellAddress*, *valuePattern* ) - - Verifies that the text in a cell of a table does not match the specified pattern. Note that this will fail if the table cell does not exist. - - **assertVisible**\ ( *elementLocator* ) - - Verifies that the specified element is both present *and* visible. An element can be rendered invisible by setting the CSS "visibility" property to "hidden", or the "display" property to "none", either for the element itself or one if its ancestors. - - **examples:** - - ============= ======== ===== - verifyVisible postcode - assertVisible postcode - ============= ======== ===== - - **assertNotVisible**\ ( *elementLocator* ) - - Verifies that the specified element is NOT visible. Elements that are simply not present are also considered invisible. - - **examples:** - - ================ ======== ===== - verifyNotVisible postcode - assertNotVisible postcode - ================ ======== ===== - - **verifyEditable / assertEditable**\ ( *inputLocator* ) - - Verifies that the specified element is editable, ie. it's an input element, and hasn't been disabled. - - **examples:** - - ============== ======== ===== - verifyEditable shape - assertEditable colour - ============== ======== ===== - - **assertNotEditable**\ ( *inputLocator* ) - - Verifies that the specified element is NOT editable, ie. it's NOT an input element, or has been disabled. - - **assertAlert**\ ( *messagePattern* ) - - Verifies that a JavaScript alert was generated, with the specified - message. - - If an alert is generated but you do not verify it, the next - Selenium action will fail. Alerts must be verified in the order - that they were generated. - - **examples:** - - ============== ==================== ===== - verifyAlert Invalid Phone Number - assertAlert Invalid Phone Number - ============== ==================== ===== - - **assertConfirmation**\ ( *messagePattern* ) - - Verifies that a JavaScript confirmation dialog was generated, with - the specified message. - - By default, the confirm function will return true, having the same - effect as manually clicking OK. This can be changed by prior - execution of the **chooseCancelOnNextConfirmation** command (see - above). - - Like alerts, any unexpected confirmation will cause the test to - fail, and confirmations must be verified in the order that they - were generated. - - **examples:** - - ================== ==================== ===== - assertConfirmation Remove this user? - verifyConfirmation Are you sure? - ================== ==================== ===== - - **assertPrompt**\ ( *messagePattern* ) - - Verifies that a JavaScript prompt dialog was generated, with the - specified message. - - Successful handling of the prompt requires prior execution of the - **answerOnNextPrompt** command (see above). - - Like alerts, unexpected prompts will cause the test to fail, and - they must be verified in the order that they were generated. - - **examples:** - - ================== ============================= ===== - answerOnNextPrompt Joe - click id=delegate - verifyPrompt Delegate to who? - ================== ============================= ===== - -------------------------------------------- -Handling of alert(), confirm() and prompt() -------------------------------------------- - - Selenium overrides the default implementations of the JavaScript - window.alert(), window.confirm() and window.prompt() functions, - enabling tests to simulate the actions of the user when these occur. - Under normal condition, no visible JavaScript dialog-box will appear. - - If your application generates alerts, confirmations, or prompts, you - *must* use assertAlert, assertConfirmation and assertPrompt (or their - "verify" equivalents) to handle them. Any unhandled alerts will result - in the test failing. - - *PROVISO:* Selenium is unable to handle alerts, confirmations, or - prompts raised during processing of the 'onload' event. In such cases - a visible dialog-box WILL appear, and Selenium will hang until you - manually handle it. This is an unfortunate restriction, but at this - time we have no solution. - ------------------------------------- -Parameter construction and Variables ------------------------------------- - - All Selenium command parameters can be constructed using both simple - variable substitution as well as full JavaScript. Both of these - mechanisms can access previously stored variables, but do so using - different syntax. - - **Stored Variables** - - The commands *store*, *storeValue* and *storeText* can be used to store a variable - value for later access. Internally, these variables are stored in a map called "storedVars", - with values keyed by the variable name. These commands are documented in the command reference. - - **Variable substitution** - - Variable substitution provides a simple way to include a previously stored variable in a - command parameter. This is a simple mechanism, by which the variable to substitute is indicated - by ${variableName}. Multiple variables can be substituted, and intermixed with static text. - - Example: - - ========== ==================== ========== - store Mr title - storeValue nameField surname - store ${title} ${surname} fullname - type textElement Full name is: ${fullname} - ========== ==================== ========== - - **JavaScript evaluation** - - JavaScript evaluation provides the full power of JavaScript in constructing a command parameter. - To use this mechanism, the *entire* parameter value must be prefixed by - 'javascript{' with a trailing '}'. The text inside the braces is evaluated as a JavaScript expression, - and can access previously stored variables using the *storedVars* map detailed above. - Note that variable substitution cannot be combined with JavaScript evaluation. - - Example: - - ========== ================================================ ========== - store javascript{'merchant' + (new Date()).getTime()} merchantId - type textElement javascript{storedVars['merchantId'].toUpperCase()} - ========== ================================================ ========== - ------------------- -Extending Selenium ------------------- - - It can be quite simple to extend Selenium, adding your own actions, assertions and locator-strategies. - This is done with JavaScript by adding methods to the Selenium object prototype, and the PageBot - object prototype. On startup, Selenium will automatically look through methods on these prototypes, - using name patterns to recognise which ones are actions, assertions and locators. - - The following examples try to give an indication of how Selenium can be extended with JavaScript. - -**Actions** - - All *doFoo* methods on the Selenium prototype are added as actions. For each action *foo* there - is also an action *fooAndWait* registered. An action method can take up to 2 parameters, which - will be passed the second and third column values in the test. - - Example: Add a "typeRepeated" action to Selenium, which types the text twice into a text box. - - :: - - Selenium.prototype.doTypeRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to type - var valueToType = text + text; - - // Replace the element text with the new text - this.page().replaceText(element, valueToType); - }; - -**Assertions** - - All *assertFoo* methods on the Selenium prototype are added as - assertions. For each assertion *foo* there is an *assertFoo* and - *verifyFoo* registered. An assert method can take up to 2 parameters, - which will be passed the second and third column values in the test. - - Example: Add a *valueRepeated* assertion, that makes sure that the - element value consists of the supplied text repeated. The 2 commands - that would be available in tests would be *assertValueRepeated* and - *verifyValueRepeated*. - - :: - - Selenium.prototype.assertValueRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to verify - var expectedValue = text + text; - - // Get the actual element value - var actualValue = element.value; - - // Make sure the actual value matches the expected - Assert.matches(expectedValue, actualValue); - }; - -**Locator Strategies** - - All *locateElementByFoo* 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. - - Example: Add a "valuerepeated=" locator, that finds the first element a value attribute equal to the the supplied value repeated. - - :: - - // The "inDocument" is a the document you are searching. - PageBot.prototype.locateElementByValueRepeated = function(text, inDocument) { - // Create the text to search for - var expectedValue = text + text; - - // Loop through all elements, looking for ones that have - // a value === our expected value - var allElements = inDocument.getElementsByTagName("*"); - for (var i = 0; i < allElements.length; i++) { - var testElement = allElements[i]; - if (testElement.value && testElement.value === expectedValue) { - return testElement; - } - } - return null; - }; - -**user-extensions.js** - - By default, Selenium looks for a file called "user-extensions.js", 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. - - 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. - ------------------- - -: diff --git a/tests/FunctionalTests/selenium/doc/testRunner.txt b/tests/FunctionalTests/selenium/doc/testRunner.txt deleted file mode 100644 index 56b949d2..00000000 --- a/tests/FunctionalTests/selenium/doc/testRunner.txt +++ /dev/null @@ -1,99 +0,0 @@ -========================= -TestRunner Reference -========================= ------------ -Test Suites ------------ - - A test suite is represented by an HTML document containing a single-column table. Each entry in the table should be a hyperlink to a test-case document. The first row will be ignored by Selenium, so this can be used for a title, and is typically used to hold a title. - - By default Selenium will attempt to load the test-suite from "tests/TestSuite.html". An alternative test-suite source can be specified by appending a "test" parameter to the TestRunner.html URL, e.g.:: - - http://localhost:8000/TestRunner.html?test=AllTests.php - - The "test" URL is interpreted relative to the location of TestRunner.html. - ----------- -Test Cases ----------- - - A test-case is represented by an HTML document, containing a table with 3 columns: *command*, *target*, *value*. Not all commands take a value, however. In this case either leave the column blank or use a   to make the table look better. - - The first row will be ignored by Selenium, so this can be used for a title or any other information. - - Example: - - ========== ============ ========== - Simple Test Table - -------------------------------------- - open /mypage - type nameField John Smith - click submitButton True - verifyText name John Smith - ========== ============ ========== - ------------------ -SetUp / TearDown ------------------ - - There are no setUp and tearDown commands in Selenium, but there is a way to handle these common testing operations. On the site being tested, create URLs for setUp and tearDown. Then, when the test runner opens these URLs, the server can do whatever setUp or tearDown is necessary. - - Example: - - For the T&E project, we wanted the functional tests to run as a dummy user. Therefore, we made a /setUpFT URL that would create a dummy user and write the userID to the page. Then, we can store this value (using the command storeValue) and use it in the script. Finally, we made a /tearDownFT URL which takes the dummy userID as a parameter and deletes the user. Therefore, our tests look like this: - - ========== ============================ ========== - Setup and Teardown - ------------------------------------------------------ - open /setUpFT - storeValue userid - open /login - type userID ${userid} - click submit - open /tearDownFT?userid=${userid} - ========== ============================ ========== - - ----------------------- -Continuous Integration ----------------------- - - Selenium can be integrated with an automated build. When the parameter "auto=true" is added to the URL, Selenium will run the entire suite of tests, and then post the results to a handling URL. The default URL is "/postResults", but an alternative handler location can be provided by specifying a "resultsUrl" parameter. - - The fields of the post are: - - ================== ====================================================================================================== - Parameter Description - ================== ====================================================================================================== - result the word "passed" or "failed" depending on whether the whole suite passed or at least one test failed. - totalTime the time in seconds for the whole suite to run - numTestPasses tht total number of tests which passed - numTestFailures the total number of tests which failed. - numCommandPasses the total number of commands which passed. - numCommandFailures the total number of commands which failed. - numCommandErrors the total number of commands which errored. - suite the suite table, including the hidden column of test results - testTable.1 the first test table - testTable.2 the second test table - ... ... - testTable.N The Nth test table - ================== ====================================================================================================== - - Therefore, the steps for continuous integration are: - 1. Create a servlet-type application at the url /postResults which can read the parameters above and write them to a file - 2. Create a script which can start up a brower and send to to the URL: selenium?auto=true - - Generally, this can be done by merely calling the browser with the URL as an argument: - firefox.exe http://localhost/selenium?auto=true - 3. Make your continuous build: - - Call the script from step 2, preferably using more than one browser - - Wait for it to finish, possibly by checking for the existence of the file(s) from step 1 - - Parse these files to determine whether the build passed or failed - - Act accordingly (send emails, update a build web page, etc.) - - ------------------- - -:Authors: Paul Gross, Jason Huggins -:Created Date: 08/23/2004 -:Modified Date: 28/01/2005 -:Created With: reStructuredText: http://docutils.sourceforge.net/rst.html diff --git a/tests/FunctionalTests/selenium/doc/testrunner.html b/tests/FunctionalTests/selenium/doc/testrunner.html deleted file mode 100644 index 86cac0cb..00000000 --- a/tests/FunctionalTests/selenium/doc/testrunner.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - - -TestRunner Reference - - - -

TestRunner Reference

-
-
-

Test Suites

-
-

A test suite is represented by an HTML document containing a single-column table. Each entry in the table should be a hyperlink to a test-case document. The first row will be ignored by Selenium, so this can be used for a title, and is typically used to hold a title.

-

By default Selenium will attempt to load the test-suite from "tests/TestSuite.html". An alternative test-suite source can be specified by appending a "test" parameter to the TestRunner.html URL, e.g.:

-
-http://localhost:8000/TestRunner.html?test=AllTests.php
-
-

The "test" URL is interpreted relative to the location of TestRunner.html.

-
-
-
-

Test Cases

-
-

A test-case is represented by an HTML document, containing a table with 3 columns: command, target, value. Not all commands take a value, however. In this case either leave the column blank or use a &nbsp; to make the table look better.

-

The first row will be ignored by Selenium, so this can be used for a title or any other information.

-

Example:

-
- ----- - - - - - - - - - - - - - - - - - - - - -
Simple Test Table
open/mypage 
typenameFieldJohn Smith
clicksubmitButtonTrue
verifyTextnameJohn Smith
-
-
-
-
-

SetUp / TearDown

-
-

There are no setUp and tearDown commands in Selenium, but there is a way to handle these common testing operations. On the site being tested, create URLs for setUp and tearDown. Then, when the test runner opens these URLs, the server can do whatever setUp or tearDown is necessary.

-

Example:

-
-

For the T&E project, we wanted the functional tests to run as a dummy user. Therefore, we made a /setUpFT URL that would create a dummy user and write the userID to the page. Then, we can store this value (using the command storeValue) and use it in the script. Finally, we made a /tearDownFT URL which takes the dummy userID as a parameter and deletes the user. Therefore, our tests look like this:

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Setup and Teardown
open/setUpFT 
storeValueuserid 
open/login 
typeuserID${userid}
clicksubmit 
open/tearDownFT?userid=${userid} 
-
-
-
-
-

Continuous Integration

-
-

Selenium can be integrated with an automated build. When the parameter "auto=true" is added to the URL, Selenium will run the entire suite of tests, and then post the results to a handling URL. The default URL is "/postResults", but an alternative handler location can be provided by specifying a "resultsUrl" parameter.

-

The fields of the post are:

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterDescription
resultthe word "passed" or "failed" depending on whether the whole suite passed or at least one test failed.
totalTimethe time in seconds for the whole suite to run
numTestPassestht total number of tests which passed
numTestFailuresthe total number of tests which failed.
numCommandPassesthe total number of commands which passed.
numCommandFailuresthe total number of commands which failed.
numCommandErrorsthe total number of commands which errored.
suitethe suite table, including the hidden column of test results
testTable.1the first test table
testTable.2the second test table
......
testTable.NThe Nth test table
-
-
-
Therefore, the steps for continuous integration are:
-
    -
  1. Create a servlet-type application at the url /postResults which can read the parameters above and write them to a file

    -
  2. -
  3. -
    Create a script which can start up a brower and send to to the URL: selenium?auto=true
    -
    -
    -
    -
  4. -
  5. -
    Make your continuous build:
    -
      -
    • Call the script from step 2, preferably using more than one browser
    • -
    • Wait for it to finish, possibly by checking for the existence of the file(s) from step 1
    • -
    • Parse these files to determine whether the build passed or failed
    • -
    • Act accordingly (send emails, update a build web page, etc.)
    • -
    -
    -
    -
  6. -
-
-
-
-
- --- - - - - - - - - - -
Authors:Paul Gross, Jason Huggins
Created Date:08/23/2004
Modified Date:28/01/2005
Created With:reStructuredText: http://docutils.sourceforge.net/rst.html
-
-
- - diff --git a/tests/FunctionalTests/selenium/doc/usage.html b/tests/FunctionalTests/selenium/doc/usage.html deleted file mode 100644 index 81ee7152..00000000 --- a/tests/FunctionalTests/selenium/doc/usage.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - Usage - - - -
-
-

Overview 

-This document details how Selenium can be deployed to test or script -web -applications.
-
-
-

Modes of Operation

-Broadly speaking there are two modes of operation for Selenium -TestRunner and Driven
-

TestRunner

-standalone pic
-
-The TestRunner mode of operation for Selenium is where its HTML & -Javascript -and the test suite are deployed alongside the Application Under Test -(AUT) on a arbitrary web server. The test suite is coded as tables in a -HTML page for each test.
-
-See test runner documentation for more -information.
-

Driven

-embedded pic 
-Driven Selenium is where the browser is under the the control of a -process on the same machine. That process is either a Java, .Net, Ruby -or Python -application and it is typically run in conjunction with a unit testing -framework like JUnit or NUnit. Also possible, is a console application -driving a browser interactively.
-
-The test script is one that would be recognisable to people adept with -unit test frameworks :
-
-  public void testOKClick() {
-    selenium.verifyTitle("First Page");
-    selenium.open("/TestPage.html");
-    selenium.click("OKButton");
-    selenium.verifyTitle("Another Page");
-  }
-
-The difference from normal unit testing is that as part of the startup, -three major things have to happen:
-
    -
  1. The test framework needs to publish a fresh copy of the AUT. -Selenium prefers to mount its own web server temporarily for the -purposes of testing.
  2. -
  3. The test framework needs to publish the static Selenium's HTML -pages and Javascript in an apparent directory -on the same web server as (1).
  4. -
  5. The test framework needs to open a browser instance and point it -to Selenium.html served in (2) above.
  6. -
-As each of these is a fairly time consuming operation, it is best that -all three of those happen in a one-time setup mode.  As such, and -even though these leverage a unit testing framework, this is definately -for acceptance or functional rather than unit-testing.
-
-Some variations in the accesibility of the the webserver in question -for testing purposes or its scriptablity mean a more complex setup is -required:
-
-Adjacent pic
-
-See the driven documentation for more -information.
-
-
-
- - diff --git a/tests/FunctionalTests/selenium/domviewer.html b/tests/FunctionalTests/selenium/domviewer.html deleted file mode 100644 index cf10cc6f..00000000 --- a/tests/FunctionalTests/selenium/domviewer.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - DOM Viewer - - - - - -

DOM Viewer

-

This page is generated using JavaScript. If you see this text, your - browser doesn't support JavaScript.

- - - diff --git a/tests/FunctionalTests/selenium/htmlutils.js b/tests/FunctionalTests/selenium/htmlutils.js deleted file mode 100644 index 73922b13..00000000 --- a/tests/FunctionalTests/selenium/htmlutils.js +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// This script contains some HTML utility functions that -// make it possible to handle elements in a way that is -// compatible with both IE-like and Mozilla-like browsers - -String.prototype.trim = function() { - var result = this.replace( /^\s+/g, "" );// strip leading - return result.replace( /\s+$/g, "" );// strip trailing -}; -String.prototype.lcfirst = function() { - return this.charAt(0).toLowerCase() + this.substr(1); -}; -String.prototype.ucfirst = function() { - return this.charAt(0).toUpperCase() + this.substr(1); -}; -String.prototype.startsWith = function(str) { - return this.indexOf(str) == 0; -}; - -// Returns the text in this element -function getText(element) { - text = ""; - - if(element.textContent) { - text = element.textContent; - } else if(element.innerText) { - text = element.innerText; - } - // Replace   with a space - // TODO - should this be in the match() code instead? - text = text.replace(/\240/g, " "); - return text.trim(); -} - -// Sets the text in this element -function setText(element, text) { - if(element.textContent) { - element.textContent = text; - } else if(element.innerText) { - element.innerText = text; - } -} - -// Get the value of an element -function getInputValue(inputElement) { - if (inputElement.type.toUpperCase() == 'CHECKBOX' || - inputElement.type.toUpperCase() == 'RADIO') - { - return (inputElement.checked ? 'on' : 'off'); - } - return inputElement.value; -} - -/* Fire an event in a browser-compatible manner */ -function triggerEvent(element, eventType, canBubble) { - canBubble = (typeof(canBubble) == undefined) ? true : canBubble; - if (element.fireEvent) { - element.fireEvent('on' + eventType); - } - else { - var evt = document.createEvent('HTMLEvents'); - evt.initEvent(eventType, canBubble, true); - element.dispatchEvent(evt); - } -} - -/* Fire a mouse event in a browser-compatible manner */ -function triggerMouseEvent(element, eventType, canBubble) { - canBubble = (typeof(canBubble) == undefined) ? true : canBubble; - if (element.fireEvent) { - element.fireEvent('on' + eventType); - } - else { - var evt = document.createEvent('MouseEvents'); - evt.initMouseEvent(eventType, canBubble, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); - element.dispatchEvent(evt); - } -} - -function removeLoadListener(element, command) { - if (window.removeEventListener) - element.removeEventListener("load", command, true); - else if (window.detachEvent) - element.detachEvent("onload", command); -} - -function addLoadListener(element, command) { - if (window.addEventListener) - element.addEventListener("load",command, true); - else if (window.attachEvent) - element.attachEvent("onload",command); -} - -function addUnloadListener(element, command) { - if (window.addEventListener) - element.addEventListener("unload",command, true); - else if (window.attachEvent) - element.attachEvent("onunload",command); -} - -/** - * Override the broken getFunctionName() method from JsUnit - * This file must be loaded _after_ the jsunitCore.js - */ -function getFunctionName(aFunction) { - var regexpResult = aFunction.toString().match(/function (\w*)/); - if (regexpResult && regexpResult[1]) { - return regexpResult[1]; - } - return 'anonymous'; -} - -function describe(object, delimiter) { - var props = new Array(); - for (var prop in object) { - props.push(prop + " -> " + object[prop]); - } - return props.join(delimiter || '\n'); -} - -PatternMatcher = function(pattern) { - this.selectStrategy(pattern); -}; -PatternMatcher.prototype = { - - selectStrategy: function(pattern) { - this.pattern = pattern; - var strategyName = 'glob'; // by default - if (/^([a-z-]+):(.*)/.test(pattern)) { - strategyName = RegExp.$1; - pattern = RegExp.$2; - } - var matchStrategy = PatternMatcher.strategies[strategyName]; - if (!matchStrategy) { - throw new SeleniumError("cannot find PatternMatcher.strategies." + strategyName); - } - this.matcher = new matchStrategy(pattern); - }, - - matches: function(actual) { - return this.matcher.matches(actual + ''); - // Note: appending an empty string avoids a Konqueror bug - } - -}; - -/** - * A "static" convenience method for easy matching - */ -PatternMatcher.matches = function(pattern, actual) { - return new PatternMatcher(pattern).matches(actual); -}; - -PatternMatcher.strategies = { - - /** - * Exact matching, e.g. "exact:***" - */ - exact: function(expected) { - this.expected = expected; - this.matches = function(actual) { - return actual == this.expected; - }; - }, - - /** - * Match by regular expression, e.g. "regexp:^[0-9]+$" - */ - regexp: function(regexpString) { - this.regexp = new RegExp(regexpString); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - }, - - /** - * "glob" (aka "wildmat") patterns, e.g. "glob:one,two,*" - */ - glob: function(globString) { - this.regexp = new RegExp(PatternMatcher.regexpFromGlob(globString)); - this.matches = function(actual) { - return this.regexp.test(actual); - }; - } - -}; - -PatternMatcher.regexpFromGlob = function(glob) { - var re = glob; - re = re.replace(/([.^$+(){}\[\]\\|])/g, "\\$1"); - re = re.replace(/\?/g, "(.|[\r\n])"); - re = re.replace(/\*/g, "(.|[\r\n])*"); - return "^" + re + "$"; -}; - -var Assert = { - - fail: function(message) { - throw new AssertionFailedError(message); - }, - - /* - * Assert.equals(comment?, expected, actual) - */ - equals: function() { - var args = new AssertionArguments(arguments); - if (args.expected === args.actual) { - return; - } - Assert.fail(args.comment + - "Expected '" + args.expected + - "' but was '" + args.actual + "'"); - }, - - /* - * Assert.matches(comment?, pattern, actual) - */ - matches: function() { - var args = new AssertionArguments(arguments); - if (PatternMatcher.matches(args.expected, args.actual)) { - return; - } - Assert.fail(args.comment + - "Actual value '" + args.actual + - "' did not match '" + args.expected + "'"); - }, - - /* - * Assert.notMtches(comment?, pattern, actual) - */ - notMatches: function() { - var args = new AssertionArguments(arguments); - if (!PatternMatcher.matches(args.expected, args.actual)) { - return; - } - Assert.fail(args.comment + - "Actual value '" + args.actual + - "' did match '" + args.expected + "'"); - } - -}; - -// Preprocess the arguments to allow for an optional comment. -function AssertionArguments(args) { - if (args.length == 2) { - this.comment = ""; - this.expected = args[0]; - this.actual = args[1]; - } else { - this.comment = args[0] + "; "; - this.expected = args[1]; - this.actual = args[2]; - } -} - - - -function AssertionFailedError(message) { - this.isAssertionFailedError = true; - this.failureMessage = message; -} - -function SeleniumError(message) { - var error = new Error(message); - error.isSeleniumError = true; - return error; -}; diff --git a/tests/FunctionalTests/selenium/index.html b/tests/FunctionalTests/selenium/index.html deleted file mode 100644 index eaaaa308..00000000 --- a/tests/FunctionalTests/selenium/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - -Selenium starting points - - - - - -

Selenium

- -

-Acceptance tests: These test-suites demonstrate/exercise the -functionality of Selenium. -

- - - -

Unit-tests: Use JsUnit to test Selenium internals.

- - - - - diff --git a/tests/FunctionalTests/selenium/install-readme.txt b/tests/FunctionalTests/selenium/install-readme.txt deleted file mode 100644 index 0946f4c4..00000000 --- a/tests/FunctionalTests/selenium/install-readme.txt +++ /dev/null @@ -1,9 +0,0 @@ -Copy the "selenium" folder to a web accessible directory in the same web server as the application you want to test. -In Apache, this would mean a subdirectory of "htdocs". - -Because of javascript security settings standard in most browsers, Selenium needs to be available on the same host and port as your application. - -Once deployed to the server, to run Selenium's self-tests, check out: -http://:/selenium/TestRunner.html - -Read the website for more details. (http://selenium.thoughtworks.com) \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/readme-selenium-fitrunner.txt b/tests/FunctionalTests/selenium/readme-selenium-fitrunner.txt deleted file mode 100644 index 7e13711e..00000000 --- a/tests/FunctionalTests/selenium/readme-selenium-fitrunner.txt +++ /dev/null @@ -1,46 +0,0 @@ -Selenium Functional Testing Tool -(c) ThoughtWorks, Inc., 2004 -- jrhuggins@thoughtworks.com - -To run a test suite with just a web browser (no server): - - Open /javascript/TestRunner.html in your browser. - Example: file:///C:/selenium/javascript/TestRunner.html - - -To run a test suite with simple web server: - - 1) Launch /javascript/startWebServer.bat - (An installation of Python is required. This works with 2.3.4, - but hasn't been tested with older versions, yet.) - - 2) Open up your browser, then goto the URL: - http://localhost:8000/TestRunner.html - (If you don't want the web server to run on port 8000, modify - \javascript\tinyWebServer.py) - -To run a different test suite from the default, use the URL syntax: - ./TestRunner.html?test={my-test-suite} - -Supported Browsers: - Microsoft Internet Explorer 6.0+ - Mozilla 1.6+ - Mozilla Firefox 0.9.3+ - - Other browsers, I'd love to add support for, but havn't yet: - Opera, Konqueror, and Safari - -Gotchas: -1) The tinyWebServer included is not meant for production use. It is only -provided to show a simple, working example of Selenium running from a web server. -(TODO- provide instructions for installing in Apache or IIS) - -2) The tinyWebServer is only available from localhost (unless you hack the source). -This was done as a security measure. - -3) The tests may not complete automatically the first time, because the browser may pop-up alert boxes: - a) Asking if you want to remember form values (click "No" or "Never for this site") - b) Warning about security implications about posting data unencrypted. - -4) You'll need to whitelist "localhost" in your pop-up blocker, if it is enabled. - diff --git a/tests/FunctionalTests/selenium/readme-selenium-rpcrunner.txt b/tests/FunctionalTests/selenium/readme-selenium-rpcrunner.txt deleted file mode 100644 index cc4e9205..00000000 --- a/tests/FunctionalTests/selenium/readme-selenium-rpcrunner.txt +++ /dev/null @@ -1,17 +0,0 @@ -Selenium RPC runner currently consists of and XML-RPC binding between the browser -and external processes. There is currently only support for Java. - -To run the tests - just cd to the java folder and execute - -ant -Dbrowser=firefox - -This will Run the Java Selenium RPC runner unit-and integration tests. -The integration test will launch a browser that loads a JsUnit -test suite, which will run the Selenium browser part of the unit tests -and integration test. - -Prereqs: -o JDK 1.4 installed -o Ant 1.6.1 or later installed -o Xalan and JUnit in $ANT_HOME/lib - diff --git a/tests/FunctionalTests/selenium/selenium-api.js b/tests/FunctionalTests/selenium/selenium-api.js deleted file mode 100644 index ddaf4699..00000000 --- a/tests/FunctionalTests/selenium/selenium-api.js +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -storedVars = new Object(); - -function Selenium(browserbot) { - this.browserbot = browserbot; - this.optionLocatorFactory = new OptionLocatorFactory(); - this.page = function() { - return browserbot.getCurrentPage(); - }; -} - -Selenium.createForFrame = function(frame) { - return new Selenium(BrowserBot.createForFrame(frame)); -}; - -/* - * Reset the browserbot when an error occurs.. - */ -Selenium.prototype.reset = function() { - storedVars = new Object(); - this.browserbot.selectWindow("null"); -}; - -/* - * Click on the located element, and attach a callback to notify - * when the page is reloaded. - */ -Selenium.prototype.doModalDialogTest = function(returnValue) { - this.browserbot.doModalDialogTest(returnValue); -}; - -/* - * Click on the located element, and attach a callback to notify - * when the page is reloaded. - */ -Selenium.prototype.doClick = function(locator) { - var element = this.page().findElement(locator); - this.page().clickElement(element); -}; - -/** - * Overwrite the text in the located text element. - * TODO fail if it can't be typed into. - */ -Selenium.prototype.doType = function(locator, newText) { - var element = this.page().findElement(locator); - this.page().replaceText(element, newText); -}; - -Selenium.prototype.findToggleButton = function(locator) { - var element = this.page().findElement(locator); - if (element.checked == null) { - Assert.fail("Element " + locator + " is not a toggle-button."); - } - return element; -} - -/** - * Check a toggle-button. - */ -Selenium.prototype.doCheck = function(locator) { - this.findToggleButton(locator).checked = true; -}; - -/** - * Uncheck a toggle-button. - */ -Selenium.prototype.doUncheck = function(locator) { - this.findToggleButton(locator).checked = false; -}; - -/** - * Select the option from the located select element. - */ -Selenium.prototype.doSelect = function(locator, optionLocator) { - var element = this.page().findElement(locator); - if (!("options" in element)) { - throw new SeleniumError("Specified element is not a Select (has no options)"); - } - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - var option = locator.findOption(element); - this.page().selectOption(element, option); -}; - -/* - * Open the browser to a new location. - */ -Selenium.prototype.doOpen = function(newLocation) { - this.browserbot.openLocation(newLocation); - return SELENIUM_PROCESS_WAIT; -}; - -/* - * Select the named window to be the active window. - */ -Selenium.prototype.doSelectWindow = function(windowName) { - this.browserbot.selectWindow(windowName); -}; - -/* - * Instruct Selenium to click Cancel on the next confirm dialog it encounters - */ -Selenium.prototype.doChooseCancelOnNextConfirmation = function() { - this.browserbot.cancelNextConfirmation(); -}; - -/* - * Instruct Selenium what to answear on the next prompt dialog it encounters - */ -Selenium.prototype.doAnswerOnNextPrompt = function(answer) { - this.browserbot.setNextPromptResult(answer); -}; - -/* - * Simulate the browser back button - */ -Selenium.prototype.doGoBack = function() { - this.page().goBack(); -}; - -/* - * Close the browser window or tab - */ -Selenium.prototype.doClose = function() { - this.page().close(); -}; - -/* - * Explicitly fire an event - */ -Selenium.prototype.doFireEvent = function(locator, event) { - var element = this.page().findElement(locator); - triggerEvent(element, event, false); -}; - -/* - * Get an alert message, or fail if there were no alerts. - */ -Selenium.prototype.getAlert = function() { - if (!this.browserbot.hasAlerts()) { - Assert.fail("There were no alerts"); - } - return this.browserbot.getNextAlert(); -}; - -/* - * Get a confirmation message, or fail if there were no confirmations. - */ -Selenium.prototype.getConfirmation = function() { - if (!this.browserbot.hasConfirmations()) { - Assert.fail("There were no confirmations"); - } - return this.browserbot.getNextConfirmation(); -}; - -/* - * Get a prompt message, or fail if there were no prompts. - */ -Selenium.prototype.getPrompt = function() { - if (! this.browserbot.hasPrompts()) { - Assert.fail("There were no prompts"); - } - return this.browserbot.getNextPrompt(); -}; - -/* - * Get the location of the current page. - */ -Selenium.prototype.getAbsoluteLocation = function() { - return this.page().location; -}; - -/* - * Verify the location of the current page ends with the expected location. - * If a querystring is provided, this is checked as well. - */ -Selenium.prototype.assertLocation = function(expectedLocation) { - var docLocation = this.page().location; - var searchPos = expectedLocation.lastIndexOf('?'); - - if (searchPos == -1) { - Assert.matches('*' + expectedLocation, docLocation.pathname); - } - else { - var expectedPath = expectedLocation.substring(0, searchPos); - Assert.matches('*' + expectedPath, docLocation.pathname); - - var expectedQueryString = expectedLocation.substring(searchPos); - Assert.equals(expectedQueryString, docLocation.search); - } -}; - -/* - * Get the title of the current page. - */ -Selenium.prototype.getTitle = function() { - return this.page().title(); -}; - - -/* - * Get the (trimmed) value of a form element. - * This is used to generate assertValue, verifyValue, ... - */ -Selenium.prototype.getValue = function(locator) { - var element = this.page().findElement(locator) - return getInputValue(element).trim(); -} - -/** - * Get the (trimmed) text of a form element. - * This is used to generate assertText, verifyText, ... - */ -Selenium.prototype.getText = function(locator) { - var element = this.page().findElement(locator); - return getText(element).trim(); -}; - -/** - * Assert that a toggle-button is checked. - */ -Selenium.prototype.assertChecked = function(locator) { - var element = this.page().findElement(locator); - if (element.checked == null) { - Assert.fail("Element " + locator + " is not a toggle-button."); - } - if (! element.checked) { - Assert.fail("Element " + locator + " is not checked."); - } -}; - -/** - * Assert that a toggle-button is NOT checked. - */ -Selenium.prototype.assertNotChecked = function(locator) { - var element = this.page().findElement(locator); - if (element.checked == null) { - Assert.fail("Element " + locator + " is not a toggle-button."); - } - if (element.checked) { - Assert.fail("Element " + locator + " is checked."); - } -}; - -/* - * Return the text for a single cell within an HTML table. - * The table locator syntax is table.row.column. - */ -Selenium.prototype.getTable = function(tableLocator) { - // This regular expression matches "tableName.row.column" - // For example, "mytable.3.4" - pattern = /(.*)\.(\d+)\.(\d+)/; - - if(!pattern.test(tableLocator)) { - throw new SeleniumError("Invalid target format. Correct format is tableName.rowNum.columnNum"); - } - - pieces = tableLocator.match(pattern); - - tableName = pieces[1]; - row = pieces[2]; - col = pieces[3]; - - var table = this.page().findElement(tableName); - if (row > table.rows.length) { - Assert.fail("Cannot access row " + row + " - table has " + table.rows.length + " rows"); - } - else if (col > table.rows[row].cells.length) { - Assert.fail("Cannot access column " + col + " - table row has " + table.rows[row].cells.length + " columns"); - } - else { - actualContent = getText(table.rows[row].cells[col]); - return actualContent.trim(); - } -}; - -/** - * Verify that the selected option satisfies the option locator. - */ -Selenium.prototype.assertSelected = function(target, optionLocator) { - var element = this.page().findElement(target); - var locator = this.optionLocatorFactory.fromLocatorString(optionLocator); - locator.assertSelected(element); -}; - -String.prototype.parseCSV = function() { - var values = this.replace(/\\,/g, "\n").split(","); - // Restore escaped commas - for (var i = 0; i < values.length; i++) { - values[i] = values[i].replace(/\n/g, ",").trim(); - } - return values; -}; - -/** - * Verify the label of all of the options in the drop=down. - */ -Selenium.prototype.assertSelectOptions = function(target, options) { - var element = this.page().findElement(target); - - var expectedOptionLabels = options.parseCSV(); - Assert.equals("Wrong number of options", expectedOptionLabels.length, element.options.length); - - for (var i = 0; i < element.options.length; i++) { - Assert.matches(expectedOptionLabels[i], element.options[i].text); - } -}; - -/** - * Get the value of an element attribute. The syntax for returning an element attribute - * is @attribute-name. Used to generate assert, verify, assertNot... - */ -Selenium.prototype.getAttribute = function(target) { - return this.page().findAttribute(target); -}; - -/* - * Asserts that the specified text is present in the page content. - */ -Selenium.prototype.assertTextPresent = function(expectedText) { - var allText = this.page().bodyText(); - - if(allText == "") { - Assert.fail("Page text not found"); - } else if(allText.indexOf(expectedText) == -1) { - Assert.fail("'" + expectedText + "' not found in page text."); - } -}; - -/* - * Asserts that the specified text is NOT present in the page content. - */ -Selenium.prototype.assertTextNotPresent = function(unexpectedText) { - var allText = this.page().bodyText(); - - if(allText == "") { - Assert.fail("Page text not found"); - } else if(allText.indexOf(unexpectedText) != -1) { - Assert.fail("'" + unexpectedText + "' was found in page text."); - } -}; - -/* - * Asserts that the specified element can be found. - */ -Selenium.prototype.assertElementPresent = function(locator) { - try { - this.page().findElement(locator); - } catch (e) { - Assert.fail("Element " + locator + " not found."); - } -}; - -/* - * Asserts that the specified element cannot be found. - */ -Selenium.prototype.assertElementNotPresent = function(locator) { - try { - this.page().findElement(locator); - } - catch (e) { - return; - } - Assert.fail("Element " + locator + " found."); -}; - -/* - * Asserts that the specified element is visible - */ -Selenium.prototype.assertVisible = function(locator) { - var element; - try { - element = this.page().findElement(locator); - } catch (e) { - Assert.fail("Element " + locator + " not present."); - } - if (! this.isVisible(element)) { - Assert.fail("Element " + locator + " not visible."); - } -}; - -/* - * Asserts that the specified element is visible - */ -Selenium.prototype.assertNotVisible = function(locator) { - var element; - try { - element = this.page().findElement(locator); - } catch (e) { - return; - } - if (this.isVisible(element)) { - Assert.fail("Element " + locator + " is visible."); - } -}; - -Selenium.prototype.isVisible = function(element) { - if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - { - var visibility = element.style["visibility"]; - var isDisplayed = element.style["display"] != "none"; - } - else - { - var visibility = this.getEffectiveStyleProperty(element, "visibility"); - var isDisplayed = this.isDisplayed(element); - } - return (visibility != "hidden" && isDisplayed); -}; - -Selenium.prototype.getEffectiveStyleProperty = function(element, property) { - var effectiveStyle = this.getEffectiveStyle(element); - var propertyValue = effectiveStyle[property]; - if (propertyValue == 'inherit' && element.parentNode.style) { - return this.getEffectiveStyleProperty(element.parentNode, property); - } - return propertyValue; -}; - -Selenium.prototype.isDisplayed = function(element) { - var display = this.getEffectiveStyleProperty(element, "display"); - if (display == "none") return false; - if (element.parentNode.style) { - return this.isDisplayed(element.parentNode); - } - return true; -}; - -Selenium.prototype.getEffectiveStyle = function(element) { - if (element.style == undefined) { - return undefined; // not a styled element - } - var window = this.browserbot.getContentWindow(); - if (window.getComputedStyle) { - // DOM-Level-2-CSS - return window.getComputedStyle(element, null); - } - if (element.currentStyle) { - // non-standard IE alternative - return element.currentStyle; - // TODO: this won't really work in a general sense, as - // currentStyle is not identical to getComputedStyle() - // ... but it's good enough for "visibility" - } - throw new SeleniumError("cannot determine effective stylesheet in this browser"); -}; - -/** - * Asserts that the specified element accepts user input visible - */ -Selenium.prototype.assertEditable = function(locator) { - var element = this.page().findElement(locator); - if (element.value == undefined) { - Assert.fail("Element " + locator + " is not an input."); - } - if (element.disabled) { - Assert.fail("Element " + locator + " is disabled."); - } -}; - -/** - * Asserts that the specified element does not accept user input - */ -Selenium.prototype.assertNotEditable = function(locator) { - var element = this.page().findElement(locator); - if (element.value == undefined) { - return; // not an input - } - if (element.disabled == false) { - Assert.fail("Element " + locator + " is editable."); - } -}; - - /* - * Return all buttons on the screen. - */ -Selenium.prototype.getAllButtons = function() { - return this.page().getAllButtons(); -}; - - /* - * Return all links on the screen. - */ -Selenium.prototype.getAllLinks = function() { - return this.page().getAllLinks(); -}; - - /* - * Return all fields on the screen. - */ -Selenium.prototype.getAllFields = function() { - return this.page().getAllFields(); -}; - -/* - * Set the context for the current Test - */ -Selenium.prototype.doContext = function(context) { - return this.page().setContext(context); -}; - -/* - * Store the value of a form input in a variable - */ -Selenium.prototype.doStoreValue = function(target, varName) { - if (!varName) { - // Backward compatibility mode: read the ENTIRE text of the page - // and stores it in a variable with the name of the target - value = this.page().bodyText(); - storedVars[target] = value; - return; - } - var element = this.page().findElement(target); - storedVars[varName] = getInputValue(element); -}; - -/* - * Store the text of an element in a variable - */ -Selenium.prototype.doStoreText = function(target, varName) { - var element = this.page().findElement(target); - storedVars[varName] = getText(element); -}; - -/* - * Store the value of an element attribute in a variable - */ -Selenium.prototype.doStoreAttribute = function(target, varName) { - storedVars[varName] = this.page().findAttribute(target); -}; - -/* - * Store the result of a literal value - */ -Selenium.prototype.doStore = function(value, varName) { - storedVars[varName] = value; -}; - - -/* - * Wait for the target to have the specified value by polling. - * The polling is done in TestLoop.kickoffNextCommandExecution() - */ -Selenium.prototype.doWaitForValue = function (target, value) { - var e = this.page().findElement(target); - testLoop.waitForCondition = function () { - return (e.value == value); - }; -}; - -/** - * Evaluate a parameter, performing javascript evaluation and variable substitution. - * If the string matches the pattern "javascript{ ... }", evaluate the string between the braces. - */ -Selenium.prototype.preprocessParameter = function(value) { - var match = value.match(/^javascript\{(.+)\}$/); - if (match && match[1]) { - return eval(match[1]).toString(); - } - return this.replaceVariables(value); -}; - -/* - * Search through str and replace all variable references ${varName} with their - * value in storedVars. - */ -Selenium.prototype.replaceVariables = function(str) { - var stringResult = str; - - // Find all of the matching variable references - var match = stringResult.match(/\$\{\w+\}/g); - if (!match) { - return stringResult; - } - - // For each match, lookup the variable value, and replace if found - for (var i = 0; match && i < match.length; i++) { - var variable = match[i]; // The replacement variable, with ${} - var name = variable.substring(2, variable.length - 1); // The replacement variable without ${} - var replacement = storedVars[name]; - if (replacement != undefined) { - stringResult = stringResult.replace(variable, replacement); - } - } - return stringResult; -}; - - -/** - * Factory for creating "Option Locators". - * An OptionLocator is an object for dealing with Select options (e.g. for - * finding a specified option, or asserting that the selected option of - * Select element matches some condition. - * The type of locator returned by the factory depends on the locator string: - * label= (OptionLocatorByLabel) - * value= (OptionLocatorByValue) - * index= (OptionLocatorByIndex) - * id= (OptionLocatorById) - * (default is OptionLocatorByLabel). - */ -function OptionLocatorFactory() { -} - -OptionLocatorFactory.prototype.fromLocatorString = function(locatorString) { - var locatorType = 'label'; - var locatorValue = locatorString; - // If there is a locator prefix, use the specified strategy - var result = locatorString.match(/^([a-zA-Z]+)=(.*)/); - if (result) { - locatorType = result[1]; - locatorValue = result[2]; - } - if (this.optionLocators == undefined) { - this.registerOptionLocators(); - } - if (this.optionLocators[locatorType]) { - return new this.optionLocators[locatorType](locatorValue); - } - throw new SeleniumError("Unkown option locator type: " + locatorType); -}; - -/** - * To allow for easy extension, all of the option locators are found by - * searching for all methods of OptionLocatorFactory.prototype that start - * with "OptionLocatorBy". - * TODO: Consider using the term "Option Specifier" instead of "Option Locator". - */ -OptionLocatorFactory.prototype.registerOptionLocators = function() { - this.optionLocators={}; - for (var functionName in this) { - var result = /OptionLocatorBy([A-Z].+)$/.exec(functionName); - if (result != null) { - var locatorName = result[1].lcfirst(); - this.optionLocators[locatorName] = this[functionName]; - } - } -}; - -/** - * OptionLocator for options identified by their labels. - */ -OptionLocatorFactory.prototype.OptionLocatorByLabel = function(label) { - this.label = label; - this.labelMatcher = new PatternMatcher(this.label); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.labelMatcher.matches(element.options[i].text)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with label '" + this.label + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedLabel = element.options[element.selectedIndex].text; - Assert.matches(this.label, selectedLabel); - }; -}; - -/** - * OptionLocator for options identified by their values. - */ -OptionLocatorFactory.prototype.OptionLocatorByValue = function(value) { - this.value = value; - this.valueMatcher = new PatternMatcher(this.value); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.valueMatcher.matches(element.options[i].value)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with value '" + this.value + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedValue = element.options[element.selectedIndex].value; - Assert.matches(this.value, selectedValue); - }; -}; - -/** - * OptionLocator for options identified by their index. - */ -OptionLocatorFactory.prototype.OptionLocatorByIndex = function(index) { - this.index = Number(index); - if (isNaN(this.index) || this.index < 0) { - throw new SeleniumError("Illegal Index: " + index); - } - - this.findOption = function(element) { - if (element.options.length <= this.index) { - throw new SeleniumError("Index out of range. Only " + element.options.length + " options available"); - } - return element.options[this.index]; - }; - - this.assertSelected = function(element) { - Assert.equals(this.index, element.selectedIndex); - }; -}; - -/** - * OptionLocator for options identified by their id. - */ -OptionLocatorFactory.prototype.OptionLocatorById = function(id) { - this.id = id; - this.idMatcher = new PatternMatcher(this.id); - this.findOption = function(element) { - for (var i = 0; i < element.options.length; i++) { - if (this.idMatcher.matches(element.options[i].id)) { - return element.options[i]; - } - } - throw new SeleniumError("Option with id '" + this.id + "' not found"); - }; - - this.assertSelected = function(element) { - var selectedId = element.options[element.selectedIndex].id; - Assert.matches(this.id, selectedId); - }; -}; - - diff --git a/tests/FunctionalTests/selenium/selenium-browserbot.js b/tests/FunctionalTests/selenium/selenium-browserbot.js deleted file mode 100644 index f2003687..00000000 --- a/tests/FunctionalTests/selenium/selenium-browserbot.js +++ /dev/null @@ -1,1001 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -/* -* This script provides the Javascript API to drive the test application contained within -* a Browser Window. -* TODO: -* Add support for more events (keyboard and mouse) -* Allow to switch "user-entry" mode from mouse-based to keyboard-based, firing different -* events in different modes. -*/ - -// The window to which the commands will be sent. For example, to click on a -// popup window, first select that window, and then do a normal click command. - - -// Although it's generally better web development practice not to use browser-detection -// (feature detection is better), the subtle browser differences that Selenium has to -// work around seem to make it necessary. Maybe as we learn more about what we need, -// we can do this in a more "feature-centric" rather than "browser-centric" way. -// TODO we should probably reuse an available browser-detection library -var browserName=navigator.appName; -var isIE = (browserName =="Microsoft Internet Explorer"); -var isKonqueror = (browserName == "Konqueror"); -var isSafari = (navigator.userAgent.indexOf('Safari') != -1); - -// Get the Gecko version as an 8 digit date. -var geckoResult = /^Mozilla\/5\.0 .*Gecko\/(\d{8}).*$/.exec(navigator.userAgent); -var geckoVersion = geckoResult == null ? null : geckoResult[1]; - -BrowserBot = function(frame) { - this.frame = frame; - this.currentPage = null; - this.currentWindowName = null; - - this.modalDialogTest = null; - this.recordedAlerts = new Array(); - this.recordedConfirmations = new Array(); - this.recordedPrompts = new Array(); - this.openedWindows = {}; - this.nextConfirmResult = true; - this.nextPromptResult = ''; - this.newPageLoaded = false; - - var self = this; - this.recordPageLoad = function() { - LOG.debug("Page load detected, location=" + self.getCurrentWindow().location); - self.currentPage = null; - self.newPageLoaded = true; - }; - - this.isNewPageLoaded = function() { - return self.newPageLoaded; - }; -}; - -BrowserBot.createForFrame = function(frame) { - var browserbot; - if (isIE) { - browserbot = new IEBrowserBot(frame); - } - else if (isKonqueror) { - browserbot = new KonquerorBrowserBot(frame); - } - else if (isSafari) { - browserbot = new SafariBrowserBot(frame); - } - else { - // Use mozilla by default - browserbot = new MozillaBrowserBot(frame); - } - - // Modify the test IFrame so that page loads are detected. - addLoadListener(browserbot.getFrame(), browserbot.recordPageLoad); - return browserbot; -}; - -BrowserBot.prototype.doModalDialogTest = function(test) { - this.modalDialogTest = test; -}; - -BrowserBot.prototype.cancelNextConfirmation = function() { - this.nextConfirmResult = false; -}; - -BrowserBot.prototype.setNextPromptResult = function(result) { - this.nextPromptResult = result; -}; - -BrowserBot.prototype.hasAlerts = function() { - return (this.recordedAlerts.length > 0) ; -}; - -BrowserBot.prototype.getNextAlert = function() { - return this.recordedAlerts.shift(); -}; - -BrowserBot.prototype.hasConfirmations = function() { - return (this.recordedConfirmations.length > 0) ; -}; - -BrowserBot.prototype.getNextConfirmation = function() { - return this.recordedConfirmations.shift(); -}; - -BrowserBot.prototype.hasPrompts = function() { - return (this.recordedPrompts.length > 0) ; -}; - -BrowserBot.prototype.getNextPrompt = function() { - return this.recordedPrompts.shift(); -}; - -BrowserBot.prototype.getFrame = function() { - return this.frame; -}; - -BrowserBot.prototype.selectWindow = function(target) { - // we've moved to a new page - clear the current one - this.currentPage = null; - this.currentWindowName = null; - if (target && target != "null") { - // If window exists - if (this.getTargetWindow(target)) { - this.currentWindowName = target; - } - } -}; - -BrowserBot.prototype.openLocation = function(target) { - // We're moving to a new page - clear the current one - this.currentPage = null; - this.newPageLoaded = false; - - this.setIFrameLocation(this.getFrame(), target); -}; - -BrowserBot.prototype.setIFrameLocation = function(iframe, location) { - iframe.src = location; -}; - -BrowserBot.prototype.getCurrentPage = function() { - if (this.currentPage == null) { - var testWindow = this.getCurrentWindow(); - this.modifyWindowToRecordPopUpDialogs(testWindow, this); - this.modifySeparateTestWindowToDetectPageLoads(testWindow); - this.currentPage = PageBot.createForWindow(testWindow); - this.newPageLoaded = false; - } - - return this.currentPage; -}; - -BrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - windowToModify.alert = function(alert) { - browserBot.recordedAlerts.push(alert); - }; - - windowToModify.confirm = function(message) { - browserBot.recordedConfirmations.push(message); - var result = browserBot.nextConfirmResult; - browserBot.nextConfirmResult = true; - return result; - }; - - windowToModify.prompt = function(message) { - browserBot.recordedPrompts.push(message); - var result = !browserBot.nextConfirmResult ? null : browserBot.nextPromptResult; - browserBot.nextConfirmResult = true; - browserBot.nextPromptResult = ''; - return result; - }; - - // Keep a reference to all popup windows by name - // note that in IE the "windowName" argument must be a valid javascript identifier, it seems. - var originalOpen = windowToModify.open; - windowToModify.open = function(url, windowName, windowFeatures, replaceFlag) { - var openedWindow = originalOpen(url, windowName, windowFeatures, replaceFlag); - selenium.browserbot.openedWindows[windowName] = openedWindow; - return openedWindow; - }; -}; - -/** - * The main IFrame has a single, long-lived onload handler that clears - * Browserbot.currentPage and sets the "newPageLoaded" flag. For separate - * windows, we need to attach a handler each time. This uses the - * "callOnWindowPageTransition" mechanism, which is implemented differently - * for different browsers. - */ -BrowserBot.prototype.modifySeparateTestWindowToDetectPageLoads = function(windowToModify) { - if (this.currentWindowName != null) { - this.callOnWindowPageTransition(this.recordPageLoad, windowToModify); - } -}; - -/** - * Call the supplied function when a the current page unloads and a new one loads. - * This is done with an "unload" handler which attaches a "load" handler. - */ -BrowserBot.prototype.callOnWindowPageTransition = function(loadFunction, windowObject) { - var attachLoadListener = function() { - if (windowObject && !windowObject.closed) { - addLoadListener(windowObject, loadFunction); - } - }; - - var unloadFunction = function() { - window.setTimeout(attachLoadListener, 0); - }; - addUnloadListener(windowObject, unloadFunction); -}; - -BrowserBot.prototype.getContentWindow = function() { - return this.getFrame().contentWindow || frames[this.getFrame().id]; -}; - -BrowserBot.prototype.getTargetWindow = function(windowName) { - LOG.debug("getTargetWindow(" + windowName + ")"); - // First look in the map of opened windows - var targetWindow = this.openedWindows[windowName]; - if (!targetWindow) { - var evalString = "this.getContentWindow().window." + windowName; - targetWindow = eval(evalString); - } - if (!targetWindow) { - throw new SeleniumError("Window does not exist"); - } - return targetWindow; -}; - -BrowserBot.prototype.getCurrentWindow = function() { - var testWindow = this.getContentWindow().window; - if (this.currentWindowName != null) { - testWindow = this.getTargetWindow(this.currentWindowName); - } - return testWindow; -}; - -function MozillaBrowserBot(frame) { - BrowserBot.call(this, frame); -} -MozillaBrowserBot.prototype = new BrowserBot; - -function KonquerorBrowserBot(frame) { - BrowserBot.call(this, frame); -} -KonquerorBrowserBot.prototype = new BrowserBot; - -KonquerorBrowserBot.prototype.setIFrameLocation = function(iframe, location) { - // Window doesn't fire onload event when setting src to the current value, - // so we set it to blank first. - iframe.src = "about:blank"; - iframe.src = location; -}; - -/** - * Call the supplied function when a the current page unloads and a new one loads. - * This is done by polling continuously until the document changes and is fully loaded. - */ -KonquerorBrowserBot.prototype.callOnWindowPageTransition = function(loadFunction, windowObject) { - // Since the unload event doesn't fire in Safari 1.3, we start polling immediately - // This works in Konqueror as well - if (windowObject && !windowObject.closed) { - LOG.debug("Starting pollForLoad"); - this.pollForLoad(loadFunction, windowObject, windowObject.document); - } -}; - -/** - * For Konqueror (and Safari), we can't catch the onload event for a separate window (as opposed to an IFrame) - * So we set up a polling timer that will keep checking the readyState of the document until it's complete. - * Since we might call this before the original page is unloaded, we check to see that the completed document - * is different from the original one. - */ -KonquerorBrowserBot.prototype.pollForLoad = function(loadFunction, windowObject, originalDocument) { - if (windowObject.closed) { - return; - } - - var sameDoc = (originalDocument === windowObject.document); - var rs = windowObject.document.readyState; - - if (!sameDoc && rs == 'complete') { - LOG.debug("pollForLoad complete: " + rs + " (" + sameDoc + ")"); - loadFunction(); - return; - } - var self = this; - LOG.debug("pollForLoad continue"); - window.setTimeout(function() {self.pollForLoad(loadFunction, windowObject, originalDocument);}, 500); -}; - -function SafariBrowserBot(frame) { - BrowserBot.call(this, frame); -} -SafariBrowserBot.prototype = new BrowserBot; - -SafariBrowserBot.prototype.setIFrameLocation = KonquerorBrowserBot.prototype.setIFrameLocation; -SafariBrowserBot.prototype.callOnWindowPageTransition = KonquerorBrowserBot.prototype.callOnWindowPageTransition; -SafariBrowserBot.prototype.pollForLoad = KonquerorBrowserBot.prototype.pollForLoad; - -function IEBrowserBot(frame) { - BrowserBot.call(this, frame); -} -IEBrowserBot.prototype = new BrowserBot; -IEBrowserBot.prototype.callOnWindowPageTransition = KonquerorBrowserBot.prototype.callOnWindowPageTransition; -IEBrowserBot.prototype.pollForLoad = KonquerorBrowserBot.prototype.pollForLoad; - -IEBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot); - - // we will call the previous version of this method from within our own interception - oldShowModalDialog = windowToModify.showModalDialog; - - windowToModify.showModalDialog = function(url, args, features) { - // Get relative directory to where TestRunner.html lives - // A risky assumption is that the user's TestRunner is named TestRunner.html - var doc_location = document.location.toString(); - var end_of_base_ref = doc_location.indexOf('TestRunner.html'); - var base_ref = doc_location.substring(0, end_of_base_ref); - - var fullURL = base_ref + "TestRunner.html?singletest=" + escape(browserBot.modalDialogTest) + "&autoURL=" + escape(url) + "&runInterval=" + runInterval; - browserBot.modalDialogTest = null; - - var returnValue = oldShowModalDialog(fullURL, args, features); - return returnValue; - }; -}; - -SafariBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) { - BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot); - - var originalOpen = windowToModify.open; - /* - * Safari seems to be broken, so that when we manually trigger the onclick method - * of a button/href, any window.open calls aren't resolved relative to the app location. - * So here we replace the open() method with one that does resolve the url correctly. - */ - windowToModify.open = function(url, windowName, windowFeatures, replaceFlag) { - - if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("/")) { - return originalOpen(url, windowName, windowFeatures, replaceFlag); - } - - // Reduce the current path to the directory - var currentPath = windowToModify.location.pathname || "/"; - currentPath = currentPath.replace(/\/[^\/]*$/, "/"); - - // Remove any leading "./" from the new url. - url = url.replace(/^\.\//, ""); - - newUrl = currentPath + url; - - return originalOpen(newUrl, windowName, windowFeatures, replaceFlag); - }; -}; - -PageBot = function(pageWindow) { - if (pageWindow) { - this.currentWindow = pageWindow; - this.currentDocument = pageWindow.document; - this.location = pageWindow.location; - this.title = function() {return this.currentDocument.title;}; - } - - // Register all locateElementBy* functions - // TODO - don't do this in the constructor - only needed once ever - this.locationStrategies = {}; - for (var functionName in this) { - var result = /^locateElementBy([A-Z].+)$/.exec(functionName); - if (result != null) { - var locatorFunction = this[functionName]; - if (typeof(locatorFunction) != 'function') { - continue; - } - // Use a specified prefix in preference to one generated from - // the function name - var locatorPrefix = locatorFunction.prefix || result[1].toLowerCase(); - this.locationStrategies[locatorPrefix] = locatorFunction; - } - } - - /** - * Find a locator based on a prefix. - */ - this.findElementBy = function(locatorType, locator, inDocument) { - var locatorFunction = this.locationStrategies[locatorType]; - if (! locatorFunction) { - throw new SeleniumError("Unrecognised locator type: '" + locatorType + "'"); - } - return locatorFunction.call(this, locator, inDocument); - }; - - /** - * The implicit locator, that is used when no prefix is supplied. - */ - this.locationStrategies['implicit'] = function(locator, inDocument) { - if (locator.startsWith('//')) { - return this.locateElementByXPath(locator, inDocument); - } - if (locator.startsWith('document.')) { - return this.locateElementByDomTraversal(locator, inDocument); - } - return this.locateElementByIdentifier(locator, inDocument); - }; - -}; - -PageBot.createForWindow = function(windowObject) { - if (isIE) { - return new IEPageBot(windowObject); - } - else if (isKonqueror) { - return new KonquerorPageBot(windowObject); - } - else if (isSafari) { - return new SafariPageBot(windowObject); - } - else { - // Use mozilla by default - return new MozillaPageBot(windowObject); - } -}; - -MozillaPageBot = function(pageWindow) { - PageBot.call(this, pageWindow); -}; -MozillaPageBot.prototype = new PageBot(); - -KonquerorPageBot = function(pageWindow) { - PageBot.call(this, pageWindow); -}; -KonquerorPageBot.prototype = new PageBot(); - -SafariPageBot = function(pageWindow) { - PageBot.call(this, pageWindow); -}; -SafariPageBot.prototype = new PageBot(); - -IEPageBot = function(pageWindow) { - PageBot.call(this, pageWindow); -}; -IEPageBot.prototype = new PageBot(); - -/* -* Finds an element on the current page, using various lookup protocols -*/ -PageBot.prototype.findElement = function(locator) { - var locatorType = 'implicit'; - var locatorString = locator; - - // If there is a locator prefix, use the specified strategy - var result = locator.match(/^([A-Za-z]+)=(.+)/); - if (result) { - locatorType = result[1].toLowerCase(); - locatorString = result[2]; - } - - var element = this.findElementBy(locatorType, locatorString, this.currentDocument); - if (element != null) { - return element; - } - for (var i = 0; i < this.currentWindow.frames.length; i++) { - element = this.findElementBy(locatorType, locatorString, this.currentWindow.frames[i].document); - if (element != null) { - return element; - } - } - - // Element was not found by any locator function. - throw new SeleniumError("Element " + locator + " not found"); -}; - -/** - * In non-IE browsers, getElementById() does not search by name. Instead, we - * we search separately by id and name. - */ -PageBot.prototype.locateElementByIdentifier = function(identifier, inDocument) { - return PageBot.prototype.locateElementById(identifier, inDocument) - || PageBot.prototype.locateElementByName(identifier, inDocument) - || null; -}; - -/** - * In IE, getElementById() also searches by name - this is an optimisation for IE. - */ -IEPageBot.prototype.locateElementByIdentifer = function(identifier, inDocument) { - return inDocument.getElementById(identifier); -}; - -/** - * Find the element with id - can't rely on getElementById, coz it returns by name as well in IE.. - */ -PageBot.prototype.locateElementById = function(identifier, inDocument) { - var element = inDocument.getElementById(identifier); - if (element && element.id === identifier) { - return element; - } - else { - return null; - } -}; - -/** - * Find an element by name, refined by (optional) element-filter - * expressions. - */ -PageBot.prototype.locateElementByName = function(locator, document) { - var elements = document.getElementsByTagName("*"); - - var filters = locator.split(' '); - filters[0] = 'name=' + filters[0]; - - while (filters.length) { - var filter = filters.shift(); - elements = this.selectElements(filter, elements, 'value'); - } - - if (elements.length > 0) { - return elements[0]; - } - return null; -}; - -/** -* Finds an element using by evaluating the "document.*" string against the -* current document object. Dom expressions must begin with "document." -*/ -PageBot.prototype.locateElementByDomTraversal = function(domTraversal, inDocument) { - if (domTraversal.indexOf("document.") != 0) { - return null; - } - - // Trim the leading 'document' - domTraversal = domTraversal.substr(9); - var locatorScript = "inDocument." + domTraversal; - var element = eval(locatorScript); - - if (!element) { - return null; - } - - return element; -}; -PageBot.prototype.locateElementByDomTraversal.prefix = "dom"; - -/** -* Finds an element identified by the xpath expression. Expressions _must_ -* begin with "//". -*/ -PageBot.prototype.locateElementByXPath = function(xpath, inDocument) { - - // Trim any trailing "/": not valid xpath, and remains from attribute - // locator. - if (xpath.charAt(xpath.length - 1) == '/') { - xpath = xpath.slice(0, -1); - } - - // Handle //tag - var match = xpath.match(/^\/\/(\w+|\*)$/); - if (match) { - var elements = inDocument.getElementsByTagName(match[1].toUpperCase()); - if (elements == null) return null; - return elements[0]; - } - - // Handle //tag[@attr='value'] - var match = xpath.match(/^\/\/(\w+|\*)\[@(\w+)=('([^\']+)'|"([^\"]+)")\]$/); - if (match) { - return this.findElementByTagNameAndAttributeValue( - inDocument, - match[1].toUpperCase(), - match[2].toLowerCase(), - match[3].slice(1, -1) - ); - } - - // Handle //tag[text()='value'] - var match = xpath.match(/^\/\/(\w+|\*)\[text\(\)=('([^\']+)'|"([^\"]+)")\]$/); - if (match) { - return this.findElementByTagNameAndText( - inDocument, - match[1].toUpperCase(), - match[2].slice(1, -1) - ); - } - - return this.findElementUsingFullXPath(xpath, inDocument); -}; - -PageBot.prototype.findElementByTagNameAndAttributeValue = function( - inDocument, tagName, attributeName, attributeValue -) { - if (isIE && attributeName == "class") { - attributeName = "className"; - } - var elements = inDocument.getElementsByTagName(tagName); - for (var i = 0; i < elements.length; i++) { - var elementAttr = elements[i].getAttribute(attributeName); - if (elementAttr == attributeValue) { - return elements[i]; - } - } - return null; -}; - -PageBot.prototype.findElementByTagNameAndText = function( - inDocument, tagName, text -) { - var elements = inDocument.getElementsByTagName(tagName); - for (var i = 0; i < elements.length; i++) { - if (getText(elements[i]) == text) { - return elements[i]; - } - } - return null; -}; - -PageBot.prototype.findElementUsingFullXPath = function(xpath, inDocument) { - if (isIE && !inDocument.evaluate) { - addXPathSupport(inDocument); - } - - alert("find by xpath"); - - // Use document.evaluate() if it's available - if (inDocument.evaluate) { - return inDocument.evaluate(xpath, inDocument, null, 0, null).iterateNext(); - } - - - - // If not, fall back to slower JavaScript implementation - var context = new XPathContext(); - - context.expressionContextNode = inDocument; - var xpathResult = new XPathParser().parse(xpath).evaluate(context); - if (xpathResult && xpathResult.toArray) { - return xpathResult.toArray()[0]; - } - return null; -}; - -/** -* Finds a link element with text matching the expression supplied. Expressions must -* begin with "link:". -*/ -PageBot.prototype.locateElementByLinkText = function(linkText, inDocument) { - var links = inDocument.getElementsByTagName('a'); - for (var i = 0; i < links.length; i++) { - var element = links[i]; - if (PatternMatcher.matches(linkText, getText(element))) { - return element; - } - } - return null; -}; -PageBot.prototype.locateElementByLinkText.prefix = "link"; - -/** -* Returns an attribute based on an attribute locator. This is made up of an element locator -* suffixed with @attribute-name. -*/ -PageBot.prototype.findAttribute = function(locator) { - // Split into locator + attributeName - var attributePos = locator.lastIndexOf("@"); - var elementLocator = locator.slice(0, attributePos); - var attributeName = locator.slice(attributePos + 1); - - // Find the element. - var element = this.findElement(elementLocator); - - // Handle missing "class" attribute in IE. - if (isIE && attributeName == "class") { - attributeName = "className"; - } - - // Get the attribute value. - var attributeValue = element.getAttribute(attributeName); - - return attributeValue ? attributeValue.toString() : null; -}; - -/* -* Select the specified option and trigger the relevant events of the element. -*/ -PageBot.prototype.selectOption = function(element, option) { - triggerEvent(element, 'focus', false); - if (!option.selected) { - option.selected = true; - triggerEvent(element, 'change', true); - } - triggerEvent(element, 'blur', false); -}; - -PageBot.prototype.replaceText = function(element, stringValue) { - triggerEvent(element, 'focus', false); - triggerEvent(element, 'select', true); - element.value=stringValue; - triggerEvent(element, 'change', true); - triggerEvent(element, 'blur', false); -}; - -MozillaPageBot.prototype.clickElement = function(element) { - - triggerEvent(element, 'focus', false); - - // Add an event listener that detects if the default action has been prevented. - // (This is caused by a javascript onclick handler returning false) - var preventDefault = false; - if (geckoVersion) { - element.addEventListener("click", function(evt) {preventDefault = evt.getPreventDefault();}, false); - } - - // Trigger the click event. - triggerMouseEvent(element, 'click', true); - - // In FireFox < 1.0 Final, and Mozilla <= 1.7.3, just sending the click event is enough. - // But in newer versions, we need to do it ourselves. - var needsProgrammaticClick = (geckoVersion > '20041025'); - // Perform the link action if preventDefault was set. - if (needsProgrammaticClick && !preventDefault) { - // Try the element itself, as well as it's parent - this handles clicking images inside links. - if (element.href) { - this.currentWindow.location.href = element.href; - } - else if (element.parentNode && element.parentNode.href) { - this.currentWindow.location.href = element.parentNode.href; - } - } - - if (this.windowClosed()) { - return; - } - - triggerEvent(element, 'blur', false); -}; - -KonquerorPageBot.prototype.clickElement = function(element) { - - triggerEvent(element, 'focus', false); - - if (element.click) { - element.click(); - } - else { - triggerMouseEvent(element, 'click', true); - } - - if (this.windowClosed()) { - return; - } - - triggerEvent(element, 'blur', false); -}; - -SafariPageBot.prototype.clickElement = function(element) { - - triggerEvent(element, 'focus', false); - - var wasChecked = element.checked; - - // For form element it is simple. - if (element.click) { - element.click(); - } - // For links and other elements, event emulation is required. - else { - triggerEvent(element, 'click', true); - - // Unfortunately, triggering the event doesn't seem to activate onclick handlers. - // We currently call onclick for the link, but I'm guessing that the onclick for containing - // elements is not being called. - var success = true; - if (element.onclick) { - var evt = document.createEvent('HTMLEvents'); - evt.initEvent('click', true, true); - var onclickResult = element.onclick(evt); - if (onclickResult === false) { - success = false; - } - } - - if (success) { - // Try the element itself, as well as it's parent - this handles clicking images inside links. - if (element.href) { - this.currentWindow.location.href = element.href; - } - else if (element.parentNode.href) { - this.currentWindow.location.href = element.parentNode.href; - } else { - // This is true for buttons outside of forms, and maybe others. - LOG.warn("Ignoring 'click' call for button outside form, or link without href." - + "Using buttons without an enclosing form can cause wierd problems with URL resolution in Safari." ); - // I implemented special handling for window.open, but unfortunately this behaviour is also displayed - // when we have a button without an enclosing form that sets document.location in the onclick handler. - // The solution is to always use an enclosing form for a button. - } - } - } - - // Onchange event is not triggered automatically in Safari. - if (isDefined(element.checked) && wasChecked != element.checked) { - triggerEvent(element, 'change', true); - } - - if (this.windowClosed()) { - return; - } - - triggerEvent(element, 'blur', false); -}; - -IEPageBot.prototype.clickElement = function(element) { - - triggerEvent(element, 'focus', false); - - var wasChecked = element.checked; - - // Set a flag that records if the page will unload - this isn't always accurate, because - // triggers the onbeforeunload event, even thought the page won't unload - var pageUnloading = false; - var pageUnloadDetector = function() {pageUnloading = true;}; - this.currentWindow.attachEvent("onbeforeunload", pageUnloadDetector); - - element.click(); - - // If the page is going to unload - still attempt to fire any subsequent events. - // However, we can't guarantee that the page won't unload half way through, so we need to handle exceptions. - try { - this.currentWindow.detachEvent("onbeforeunload", pageUnloadDetector); - - if (this.windowClosed()) { - return; - } - - // Onchange event is not triggered automatically in IE. - if (isDefined(element.checked) && wasChecked != element.checked) { - triggerEvent(element, 'change', true); - } - - triggerEvent(element, 'blur', false); - } - catch (e) { - // If the page is unloading, we may get a "Permission denied" or "Unspecified error". - // Just ignore it, because the document may have unloaded. - if (pageUnloading) { - LOG.warn("Caught exception when firing events on unloading page: " + e.message); - return; - } - throw e; - } -}; - -PageBot.prototype.windowClosed = function(element) { - return this.currentWindow.closed; -}; - -PageBot.prototype.bodyText = function() { - return getText(this.currentDocument.body); -}; - -PageBot.prototype.getAllButtons = function() { - var elements = this.currentDocument.getElementsByTagName('input'); - var result = ''; - - for (var i = 0; i < elements.length; i++) { - if (elements[i].type == 'button' || elements[i].type == 'submit' || elements[i].type == 'reset') { - result += elements[i].id; - - result += ','; - } - } - - return result; -}; - - -PageBot.prototype.getAllFields = function() { - var elements = this.currentDocument.getElementsByTagName('input'); - var result = ''; - - for (var i = 0; i < elements.length; i++) { - if (elements[i].type == 'text') { - result += elements[i].id; - - result += ','; - } - } - - return result; -}; - -PageBot.prototype.getAllLinks = function() { - var elements = this.currentDocument.getElementsByTagName('a'); - var result = ''; - - for (var i = 0; i < elements.length; i++) { - result += elements[i].id; - - result += ','; - } - - return result; -}; - -PageBot.prototype.setContext = function(strContext) { - //set the current test title - context.innerHTML=strContext; -}; - -function isDefined(value) { - return typeof(value) != undefined; -} - -PageBot.prototype.goBack = function() { - this.currentWindow.history.back(); -}; - -PageBot.prototype.goForward = function() { - this.currentWindow.history.forward(); -}; - -PageBot.prototype.close = function() { - this.currentWindow.close(); -}; - -/** - * Refine a list of elements using a filter. - */ -PageBot.prototype.selectElementsBy = function(filterType, filter, elements) { - var filterFunction = PageBot.filterFunctions[filterType]; - if (! filterFunction) { - throw new SeleniumError("Unrecognised element-filter type: '" + filterType + "'"); - } - - return filterFunction(filter, elements); -}; - -PageBot.filterFunctions = {}; - -PageBot.filterFunctions.name = function(name, elements) { - var selectedElements = []; - for (var i = 0; i < elements.length; i++) { - if (elements[i].name === name) { - selectedElements.push(elements[i]); - } - } - return selectedElements; -}; - -PageBot.filterFunctions.value = function(value, elements) { - var selectedElements = []; - for (var i = 0; i < elements.length; i++) { - if (elements[i].value === value) { - selectedElements.push(elements[i]); - } - } - return selectedElements; -}; - -PageBot.filterFunctions.index = function(index, elements) { - index = Number(index); - if (isNaN(index) || index < 0) { - throw new SeleniumError("Illegal Index: " + index); - } - if (elements.length <= index) { - throw new SeleniumError("Index out of range: " + index); - } - return [elements[index]]; -}; - -PageBot.prototype.selectElements = function(filterExpr, elements, defaultFilterType) { - - var filterType = (defaultFilterType || 'value'); - - // If there is a filter prefix, use the specified strategy - var result = filterExpr.match(/^([A-Za-z]+)=(.+)/); - if (result) { - filterType = result[1].toLowerCase(); - filterExpr = result[2]; - } - - return this.selectElementsBy(filterType, filterExpr, elements); -}; - diff --git a/tests/FunctionalTests/selenium/selenium-commandhandlers.js b/tests/FunctionalTests/selenium/selenium-commandhandlers.js deleted file mode 100644 index 10e2a518..00000000 --- a/tests/FunctionalTests/selenium/selenium-commandhandlers.js +++ /dev/null @@ -1,291 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ -function CommandHandlerFactory() { - this.actions = {}; - this.asserts = {}; - this.accessors = {}; - - var self = this; - - this.registerAction = function(name, action, wait) { - var handler = new ActionHandler(action, wait); - this.actions[name] = handler; - }; - - this.registerAccessor = function(name, accessor) { - var handler = new AccessorHandler(accessor); - this.accessors[name] = handler; - }; - - this.registerAssert = function(name, assertion, haltOnFailure) { - var handler = new AssertHandler(assertion, haltOnFailure); - this.asserts[name] = handler; - }; - - this.registerAssertUsingMatcherHandler = function(name, matcherHandler, haltOnFailure) { - var handler = new AssertUsingMatcherHandler(matcherHandler, haltOnFailure); - this.asserts[name] = handler; - } - - this.getCommandHandler = function(name) { - return this.actions[name] || this.accessors[name] || this.asserts[name] || null; - }; - - this.registerAll = function(commandObject) { - registerAllActions(commandObject); - registerAllAsserts(commandObject); - registerAllAccessors(commandObject); - }; - - var registerAllActions = function(commandObject) { - for (var functionName in commandObject) { - var result = /^do([A-Z].+)$/.exec(functionName); - if (result != null) { - var actionName = result[1].lcfirst(); - - // Register the action without the wait flag. - var action = commandObject[functionName]; - self.registerAction(actionName, action, false); - - // Register actionName + "AndWait" with the wait flag; - var waitActionName = actionName + "AndWait"; - self.registerAction(waitActionName, action, true); - } - } - }; - - var registerAllAsserts = function(commandObject) { - for (var functionName in commandObject) { - var result = /^assert([A-Z].+)$/.exec(functionName); - if (result != null) { - var assert = commandObject[functionName]; - - // Register the assert with the "assert" prefix, and halt on failure. - var assertName = functionName; - self.registerAssert(assertName, assert, true); - - // Register the assert with the "verify" prefix, and do not halt on failure. - var verifyName = "verify" + result[1]; - self.registerAssert(verifyName, assert, false); - } - } - }; - - // Given an accessor function, return a function that matches against the command.value - // the value returned by the accessor when applied to a command.target. - // Used by commands that take a target and a value (e.g. assertValue | target | value) - this.createMatcherHandlerFromSingleArgAccessor = function(accessor) { - return function(seleniumApi, command) { - var accessorResult = accessor.call(seleniumApi, command.target); - if (PatternMatcher.matches(command.value, accessorResult)) { - return new MatcherHandlerResult(true, "Actual value '" + accessorResult + "' did match '" + command.value + "'"); - } else { - return new MatcherHandlerResult(false, "Actual value '" + accessorResult + "' did not match '" + command.value + "'"); - } - }; - }; - - // Given an accessor function, return a function that matches against the command.target - // the value returned by the (no-arg) accessor returns a value that matches against the command.target - // Used by commands that only take a target (e.g. assertTitle | target |  ) - this.createMatcherHandlerFromNoArgAccessor = function(accessor) { - return function(seleniumApi, command) { - var accessorResult = accessor.call(seleniumApi); - if (PatternMatcher.matches(command.target, accessorResult)) { - return new MatcherHandlerResult(true, "Actual value '" + accessorResult + "' did match '" + command.target + "'"); - } else { - return new MatcherHandlerResult(false, "Actual value '" + accessorResult + "' did not match '" + command.target + "'"); - } - }; - }; - - // Given a matcherHandler function, return a function that returns the same result - // as the matcherHandler, but with the result negated. - // Used to create assertNot and verifyNot commands (and soon hopefully waitForNot commands). - this.createMatcherHandlerNegator = function(matcherHandler) { - return function(seleniumApi, command) { - var result = matcherHandler(seleniumApi, command); - result.didMatch = ! result.didMatch; - return result; - }; - }; - - // Register an assertion, a verification, a negative assertion, - // and a negative verification based on the specified accessor. - this.registerAssertionsBasedOnAccessor = function(accessor, baseName) { - if (accessor.length > 1) { - return; - } - var matcherHandler; - if (accessor.length == 1) { - matcherHandler = self.createMatcherHandlerFromSingleArgAccessor(accessor); - } else { - matcherHandler = self.createMatcherHandlerFromNoArgAccessor(accessor); - } - // Register an assert with the "assert" prefix, and halt on failure. - self.registerAssertUsingMatcherHandler("assert" + baseName, matcherHandler, true); - // Register a verify with the "verify" prefix, and do not halt on failure. - self.registerAssertUsingMatcherHandler("verify" + baseName, matcherHandler, false); - - var negativeMatcherHandler = self.createMatcherHandlerNegator(matcherHandler); - // Register an assertNot with the "assertNot" prefix, and halt on failure. - self.registerAssertUsingMatcherHandler("assertNot"+baseName, negativeMatcherHandler, true); - // Register a verifyNot with the "verifyNot" prefix, and do not halt on failure. - self.registerAssertUsingMatcherHandler("verifyNot"+baseName, negativeMatcherHandler, false); - }; - - // Methods of the form getFoo(target) result in commands: - // getFoo, assertFoo, verifyFoo, assertNotFoo, verifyNotFoo - var registerAllAccessors = function(commandObject) { - for (var functionName in commandObject) { - var match = /^get([A-Z].+)$/.exec(functionName); - if (match != null) { - var accessor = commandObject[functionName]; - var baseName = match[1]; - self.registerAccessor(functionName, accessor); - self.registerAssertionsBasedOnAccessor(accessor, baseName); - } - } - }; - - -} - -function MatcherHandlerResult(didMatch, message) { - this.didMatch = didMatch; - this.message = message; -} - -// NOTE: The CommandHandler is effectively an abstract base for ActionHandler, -// AccessorHandler and AssertHandler. -function CommandHandler(type, haltOnFailure, executor) { - this.type = type; - this.haltOnFailure = haltOnFailure; - this.executor = executor; -} -CommandHandler.prototype.execute = function(seleniumApi, command) { - return new CommandResult(this.executor.call(seleniumApi, command.target, command.value)); -}; - -function ActionHandler(action, wait) { - CommandHandler.call(this, "action", true, action); - if (wait) { - this.wait = true; - } -} -ActionHandler.prototype = new CommandHandler; -ActionHandler.prototype.execute = function(seleniumApi, command) { - if ( seleniumApi.browserbot.hasAlerts() ) { - throw new SeleniumCommandError("There was an unexpected Alert! [" + seleniumApi.browserbot.getNextAlert() + "]"); - } - if ( seleniumApi.browserbot.hasConfirmations() ) { - throw new SeleniumCommandError("There was an unexpected Confirmation! [" + seleniumApi.browserbot.getNextConfirmation() + "]"); - } - var processState = this.executor.call(seleniumApi, command.target, command.value); - // If the handler didn't return a wait flag, check to see if the - // handler was registered with the wait flag. - if (processState == undefined && this.wait) { - processState = SELENIUM_PROCESS_WAIT; - } - return new CommandResult(processState); -}; - -function AccessorHandler(accessor) { - CommandHandler.call(this, "accessor", true, accessor); -} -AccessorHandler.prototype = new CommandHandler; -AccessorHandler.prototype.execute = function(seleniumApi, command) { - var returnValue = this.executor.call(seleniumApi, command.target, command.value); - var result = new CommandResult(); - result.result = returnValue; - return result; -}; - -/** - * Abstract handler for assertions and verifications. - * Subclasses need to override executeAssertion() which in turn - * should throw an AssertFailedError if the assertion is to fail. - */ -function AbstractAssertHandler(assertion, haltOnFailure) { - CommandHandler.call(this, "assert", haltOnFailure || false, assertion); -} -AbstractAssertHandler.prototype = new CommandHandler; -AbstractAssertHandler.prototype.execute = function(seleniumApi, command) { - var result = new CommandResult(); - try { - this.executeAssertion(seleniumApi, command); - result.passed = true; - } catch (e) { - // If this is not a AssertionFailedError, or we should haltOnFailure, rethrow. - if (!e.isAssertionFailedError) { - throw e; - } - if (this.haltOnFailure) { - var error = new SeleniumCommandError(e.failureMessage); - throw error; - } - result.failed = true; - result.failureMessage = e.failureMessage; - } - return result; -}; - -/** - * Simple assertion handler whose command is expected to do the actual assertion. - */ -function AssertHandler(assertion, haltOnFailure) { - CommandHandler.call(this, "assert", haltOnFailure || false, assertion); -}; -AssertHandler.prototype = new AbstractAssertHandler; -AssertHandler.prototype.executeAssertion = function(seleniumApi, command) { - this.executor.call(seleniumApi, command.target, command.value); -}; - -/** - * Assertion handler whose command is expected to be a matcher-handler - */ -function AssertUsingMatcherHandler(matcherHandler, haltOnFailure) { - CommandHandler.call(this, "assert", haltOnFailure || false, matcherHandler); -}; -AssertUsingMatcherHandler.prototype = new AbstractAssertHandler; -AssertUsingMatcherHandler.prototype.executeAssertion = function(seleniumApi, command) { - var matcherResult = this.executor(seleniumApi, command); - if (!matcherResult.didMatch) { - Assert.fail(matcherResult.message); - } -}; - - -function CommandResult(processState) { - this.processState = processState; - this.result = "OK"; -} - -function SeleniumCommand(command, target, value) { - this.command = command; - this.target = target; - this.value = value; -} - -// TODO: dkemp - This is the same as SeleniumError as defined in selenium-browserbot.js -// I defined a new error simply to avoid creating a new dependency. -// Need to revisit to avoid this duplication. -function SeleniumCommandError(message) { - var error = new Error(message); - error.isSeleniumError = true; - return error; -}; diff --git a/tests/FunctionalTests/selenium/selenium-domviewer.js b/tests/FunctionalTests/selenium/selenium-domviewer.js deleted file mode 100644 index 01a384f5..00000000 --- a/tests/FunctionalTests/selenium/selenium-domviewer.js +++ /dev/null @@ -1,188 +0,0 @@ -var HIDDEN="hidden"; -var LEVEL = "level"; -var PLUS_SRC="dom-images/butplus.gif"; -var MIN_SRC="dom-images/butmin.gif"; -var newRoot; -var maxColumns=1; - -function loadDomViewer() { - // See if the rootDocument variable has been set on this window. - var rootDocument = window.rootDocument; - - // If not look to the opener for an explicity rootDocument variable, otherwise, use the opener document - if (!rootDocument && window.opener) { - rootDocument = window.opener.rootDocument || window.opener.document; - } - - if (rootDocument) { - document.body.innerHTML = displayDOM(rootDocument); - } - else { - document.body.innerHTML = "Must specify rootDocument for window. This can be done by setting the rootDocument variable on this window, or on the opener window for a popup window."; - } -} - - -function displayDOM(root){ - var str = ""; - str+=""; - str += treeTraversal(root,0); - // to make table columns work well. - str += ""; - for (var i=0; i < maxColumns; i++) { - str+= ""; - } - str += ""; - str += "
    
"; - return str; -} - -function checkForChildren(element){ - if(!element.hasChildNodes()) - return false; - - var nodes = element.childNodes; - var size = nodes.length; - var count=0; - - for(var i=0; i< size; i++){ - var node = nodes.item(i); - //if(node.toString()=="[object Text]"){ - //this is equalent to the above - //but will work with more browsers - if(node.nodeType!=1){ - count++; - } - } - - if(count == size) - return false; - else - return true; -} - -function treeTraversal(root, level){ - var str = ""; - var nodes= null; - var size = null; - //it is supposed to show the last node, - //but the last node is always nodeText type - //and we don't show it - if(!root.hasChildNodes()) - return "";//displayNode(root,level,false); - - nodes = root.childNodes; - size = nodes.length; - - for(var i=0; i< size; i++){ - var element = nodes.item(i); - //if the node is textNode, don't display - if(element.nodeType==1){ - str+= displayNode(element,level,checkForChildren(element)); - str+=treeTraversal(element, level+1); - } - } - return str; -} - -function displayNode(element, level, isLink){ - nodeContent = getNodeContent(element); - columns = Math.round((nodeContent.length / 12) + 0.5); - if (columns + level > maxColumns) { - maxColumns = columns + level; - } - var str =""; - for (var i=0; i < level; i++) - str+= " "; - str+=""; - if(isLink){ - str+='
'; - str+=''; - } - str += nodeContent; - if(isLink) - str+=""; - return str; -} - -function getNodeContent(element) { - str = ""; - id =""; - if (element.id != null && element.id != "") { - id = " ID(" + element.id +")"; - } - name =""; - if (element.name != null && element.name != "") { - name = " NAME(" + element.name + ")"; - } - value =""; - if (element.value != null && element.value != "") { - value = " VALUE(" + element.value + ")"; - } - href =""; - if (element.href != null && element.href != "") { - href = " HREF(" + element.href + ")"; - } - text =""; - if (element.text != null && element.text != "" && element.text != "undefined") { - text = " #TEXT(" + trim(element.text) +")"; - } - str+=" "+ element.nodeName + id + name + value + href + text + ""; - return str; - -} - -function trim(val) { - val2 = val.substring(0,20) + " "; - var spaceChr = String.fromCharCode(32); - var length = val2.length; - var retVal = ""; - var ix = length -1; - - while(ix > -1){ - if(val2.charAt(ix) == spaceChr) { - } else { - retVal = val2.substring(0, ix +1); - break; - } - ix = ix-1; - } - if (val.length > 20) { - retVal += "..."; - } - return retVal; -} - -function hide(hlink){ - var isHidden = false; - var image = hlink.firstChild; - if(image.src.toString().indexOf(MIN_SRC)!=-1){ - image.src=PLUS_SRC; - isHidden=true; - }else{ - image.src=MIN_SRC; - } - var rowObj= hlink.parentNode.parentNode; - var rowLevel = parseInt(rowObj.className.substring(LEVEL.length)); - - var sibling = rowObj.nextSibling; - var siblingLevel = sibling.className.substring(LEVEL.length); - if(siblingLevel.indexOf(HIDDEN)!=-1){ - siblingLevel = siblingLevel.substring(0,siblingLevel.length - HIDDEN.length-1); - } - siblingLevel=parseInt(siblingLevel); - while(sibling!=null && rowLevel 0) { - // Make the previous row green or red depending if the test passed or failed - if(testFailed) - setCellColor(suiteTable.rows, currentTestRow, 0, failColor); - else - setCellColor(suiteTable.rows, currentTestRow, 0, passColor); - - // Set the results from the previous test run - setResultsData(suiteTable, currentTestRow); - } - - currentTestRow++; - - // If we are done with all of the tests, set the title bar as pass or fail - if(currentTestRow >= suiteTable.rows.length) { - if(suiteFailed) - setCellColor(suiteTable.rows, 0, 0, failColor); - else - setCellColor(suiteTable.rows, 0, 0, passColor); - - // If this is an automated run (i.e., build script), then submit - // the test results by posting to a form - if (isAutomatedRun()) - postTestResults(suiteFailed, suiteTable); - } - - else { - // Make the current row blue - setCellColor(suiteTable.rows, currentTestRow, 0, workingColor); - - testLink = suiteTable.rows[currentTestRow].cells[0].getElementsByTagName("a")[0]; - testLink.focus(); - - var testFrame = getTestFrame(); - addLoadListener(testFrame, startTest); - - selenium.browserbot.setIFrameLocation(testFrame, testLink.href); - } -} - -function setCellColor(tableRows, row, col, colorStr) { - tableRows[row].cells[col].bgColor = colorStr; -} - -// Sets the results from a test into a hidden column on the suite table. So, -// for each tests, the second column is set to the HTML from the test table. -function setResultsData(suiteTable, row) { - // Create a text node of the test table - var resultTable = getIframeDocument(getTestFrame()).body.innerHTML; - if (!resultTable) return; - - var tableNode = suiteTable.ownerDocument.createElement("div"); - tableNode.innerHTML = resultTable; - - var new_column = suiteTable.ownerDocument.createElement("td"); - new_column.appendChild(tableNode); - - // Set the column to be invisible - new_column.style.cssText = "display: none;"; - - // Add the invisible column - suiteTable.rows[row].appendChild(new_column); -} - -// Post the results to a servlet, CGI-script, etc. The URL of the -// results-handler defaults to "/postResults", but an alternative location -// can be specified by providing a "resultsUrl" query parameter. -// -// Parameters passed to the results-handler are: -// result: passed/failed depending on whether the suite passed or failed -// totalTime: the total running time in seconds for the suite. -// -// numTestPasses: the total number of tests which passed. -// numTestFailures: the total number of tests which failed. -// -// numCommandPasses: the total number of commands which passed. -// numCommandFailures: the total number of commands which failed. -// numCommandErrors: the total number of commands which errored. -// -// suite: the suite table, including the hidden column of test results -// testTable.1 to testTable.N: the individual test tables -// -function postTestResults(suiteFailed, suiteTable) { - - form = document.createElement("form"); - document.body.appendChild(form); - - form.id = "resultsForm"; - form.method="post"; - form.target="myiframe"; - - var resultsUrl = getQueryParameter("resultsUrl"); - if (!resultsUrl) { - resultsUrl = "./postResults"; - } - - var actionAndParameters = resultsUrl.split('?',2); - form.action = actionAndParameters[0]; - var resultsUrlQueryString = actionAndParameters[1]; - - form.createHiddenField = function(name, value) { - input = document.createElement("input"); - input.type = "hidden"; - input.name = name; - input.value = value; - this.appendChild(input); - }; - - if (resultsUrlQueryString) { - var clauses = resultsUrlQueryString.split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=',2); - var key = unescape(keyValuePair[0]); - var value = unescape(keyValuePair[1]); - form.createHiddenField(key, value); - } - } - - form.createHiddenField("result", suiteFailed == true ? "failed" : "passed"); - - form.createHiddenField("totalTime", Math.floor((currentTime - startTime) / 1000)); - form.createHiddenField("numTestPasses", numTestPasses); - form.createHiddenField("numTestFailures", numTestFailures); - form.createHiddenField("numCommandPasses", numCommandPasses); - form.createHiddenField("numCommandFailures", numCommandFailures); - form.createHiddenField("numCommandErrors", numCommandErrors); - - // Create an input for each test table. The inputs are named - // testTable.1, testTable.2, etc. - for (rowNum = 1; rowNum < suiteTable.rows.length;rowNum++) { - // If there is a second column, then add a new input - if (suiteTable.rows[rowNum].cells.length > 1) { - var resultCell = suiteTable.rows[rowNum].cells[1]; - form.createHiddenField("testTable." + rowNum, resultCell.innerHTML); - // remove the resultCell, so it's not included in the suite HTML - resultCell.parentNode.removeChild(resultCell); - } - } - - // Add HTML for the suite itself - form.createHiddenField("suite", suiteTable.parentNode.innerHTML); - - form.submit(); - document.body.removeChild(form); - -} - -function printMetrics() { - setText(document.getElementById("commandPasses"), numCommandPasses); - setText(document.getElementById("commandFailures"), numCommandFailures); - setText(document.getElementById("commandErrors"), numCommandErrors); - setText(document.getElementById("testRuns"), numTestPasses + numTestFailures); - setText(document.getElementById("testFailures"), numTestFailures); - - currentTime = new Date().getTime(); - - timeDiff = currentTime - startTime; - totalSecs = Math.floor(timeDiff / 1000); - - minutes = Math.floor(totalSecs / 60); - seconds = totalSecs % 60; - - setText(document.getElementById("elapsedTime"), pad(minutes)+":"+pad(seconds)); -} - -// Puts a leading 0 on num if it is less than 10 -function pad (num) { - return (num > 9) ? num : "0" + num; -} - -/* - * Register all of the built-in command handlers with the CommandHandlerFactory. - * TODO work out an easy way for people to register handlers without modifying the Selenium sources. - */ -function registerCommandHandlers() { - commandFactory = new CommandHandlerFactory(); - commandFactory.registerAll(selenium); - -} - -function initialiseTestLoop() { - testLoop = new TestLoop(commandFactory); - - testLoop.getCommandInterval = function() { return runInterval; }; - testLoop.firstCommand = nextCommand; - testLoop.nextCommand = nextCommand; - testLoop.commandStarted = commandStarted; - testLoop.commandComplete = commandComplete; - testLoop.commandError = commandError; - testLoop.testComplete = testComplete; - testLoop.pause = function() { - document.getElementById('continueTest').disabled = false; - }; - return testLoop; -} - -function nextCommand() { - if (currentCommandRow >= inputTableRows.length - 1) { - return null; - } - - currentCommandRow++; - - var commandName = getCellText(currentCommandRow, 0); - var target = getCellText(currentCommandRow, 1); - var value = getCellText(currentCommandRow, 2); - - var command = new SeleniumCommand(commandName, target, removeNbsp(value)); - return command; -} - -function removeNbsp(value) -{ - return value.replace(/\240/g, ""); -} - -function scrollIntoView(element) { - if (element.scrollIntoView) { - element.scrollIntoView(false); - return; - } - // TODO: work out how to scroll browsers that don't support - // scrollIntoView (like Konqueror) -} - -function commandStarted() { - inputTableRows[currentCommandRow].bgColor = workingColor; - scrollIntoView(inputTableRows[currentCommandRow].cells[0]); - printMetrics(); -} - -function commandComplete(result) { - if (result.failed) { - setRowFailed(result.failureMessage, FAILURE); - } else if (result.passed) { - setRowPassed(); - } else { - setRowWhite(); - } -} - -function commandError(errorMessage) { - setRowFailed(errorMessage, ERROR); -} - -function setRowWhite() { - inputTableRows[currentCommandRow].bgColor = "white"; -} - -function setRowPassed() { - numCommandPasses += 1; - - // Set cell background to green - inputTableRows[currentCommandRow].bgColor = passColor; -} - -function setRowFailed(errorMsg, failureType) { - if (failureType == ERROR) - numCommandErrors += 1; - else if (failureType == FAILURE) - numCommandFailures += 1; - - // Set cell background to red - inputTableRows[currentCommandRow].bgColor = failColor; - - // Set error message - inputTableRows[currentCommandRow].cells[2].innerHTML = errorMsg; - inputTableRows[currentCommandRow].title = errorMsg; - testFailed = true; - suiteFailed = true; -} - -function testComplete() { - if(testFailed) { - inputTableRows[0].bgColor = failColor; - numTestFailures += 1; - } - else { - inputTableRows[0].bgColor = passColor; - numTestPasses += 1; - } - - printMetrics(); - - window.setTimeout("runNextTest()", 1); -} - -function getCellText(rowNumber, columnNumber) { - var cell = inputTableRows[rowNumber].cells[columnNumber]; - if (! cell.cachedText) { - cell.cachedText = getText(cell); - } - return cell.cachedText; -} - -Selenium.prototype.doPause = function(waitTime) { - testLoop.pauseInterval = waitTime; -}; diff --git a/tests/FunctionalTests/selenium/selenium-logging.js b/tests/FunctionalTests/selenium/selenium-logging.js deleted file mode 100644 index d0305c08..00000000 --- a/tests/FunctionalTests/selenium/selenium-logging.js +++ /dev/null @@ -1,88 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -var Logger = function() { - this.logWindow = null; -} -Logger.prototype = { - - getLogWindow: function() { - if (this.logWindow && this.logWindow.closed) { - this.logWindow = null; - } - return this.logWindow; - }, - - openLogWindow: function() { - this.logWindow = window.open( - "SeleniumLog.html", "SeleniumLog", - "width=600,height=250,bottom=0,right=0,status,scrollbars,resizable" - ); - return this.logWindow; - }, - - show: function() { - if (! this.getLogWindow()) { - this.openLogWindow(); - } - }, - - log: function(message, className) { - var logWindow = this.getLogWindow(); - if (logWindow) { - if (logWindow.append) { - logWindow.append(message, className); - } - } - }, - - debug: function(message) { - this.log(message, "debug"); - }, - - info: function(message) { - this.log(message, "info"); - }, - - warn: function(message) { - this.log(message, "warn"); - }, - - error: function(message) { - this.log(message, "error"); - }, - - exception: function(exception) { - var msg = "Unexpected Exception: " + describe(exception, ', '); - this.error(msg); - } - -}; - -var LOG = new Logger(); - -function noop() {}; - -var DummyLogger = function() {}; -DummyLogger.prototype = { - show: noop, - log: noop, - debug: noop, - info: noop, - warn: noop, - error: noop -}; - diff --git a/tests/FunctionalTests/selenium/selenium-logo.graffle b/tests/FunctionalTests/selenium/selenium-logo.graffle deleted file mode 100644 index e605f4da..00000000 --- a/tests/FunctionalTests/selenium/selenium-logo.graffle +++ /dev/null @@ -1,509 +0,0 @@ - - - - - CanvasColor - - w - 1 - - ColumnAlign - 1 - ColumnSpacing - 36 - CreationDate - 2005-04-17 21:44:18 -0500 - Creator - Paul Hammant - GraphDocumentVersion - 4 - GraphicsList - - - Bounds - {{54, 96}, {84, 57}} - Class - ShapedGraphic - ID - 6 - Shape - Rectangle - Style - - fill - - Draws - NO - - stroke - - Color - - b - 1 - g - 1 - r - 1 - - - - - - Bounds - {{55, 135.875}, {42, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 5 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\mac\ansicpg10000\cocoartf102 -{\fonttbl\f0\fswiss\fcharset77 Helvetica;} -{\colortbl;\red255\green255\blue255;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs24 \cf2 78.96} - - Wrap - NO - - - Bounds - {{55, 109}, {84, 22}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - Helvetica - Size - 12 - - HFlip - YES - ID - 4 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\mac\ansicpg10000\cocoartf102 -{\fonttbl\f0\fswiss\fcharset77 Helvetica;} -{\colortbl;\red255\green255\blue255;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs36 \cf2 selenium} - - Wrap - NO - - - Bounds - {{115, 98.125}, {25, 14}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - ID - 3 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\mac\ansicpg10000\cocoartf102 -{\fonttbl\f0\fswiss\fcharset77 Helvetica;} -{\colortbl;\red255\green255\blue255;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\fs24 \cf2 34} - - Wrap - NO - - - Bounds - {{56, 93.625}, {30, 23}} - Class - ShapedGraphic - FitText - YES - Flow - Resize - FontInfo - - Font - LucidaBlackletter - Size - 18 - - ID - 2 - Shape - Rectangle - Style - - fill - - Draws - NO - - shadow - - Draws - NO - - stroke - - Draws - NO - - - Text - - Text - {\rtf1\mac\ansicpg10000\cocoartf102 -{\fonttbl\f0\fnil\fcharset77 LucidaBlackletter;} -{\colortbl;\red255\green255\blue255;\red255\green255\blue255;} -\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc - -\f0\b\fs36 \cf2 Se} - - Wrap - NO - - - Bounds - {{50, 91}, {92, 67}} - Class - ShapedGraphic - ID - 1 - Shape - Rectangle - Style - - fill - - Color - - b - 0.0556939 - g - 0.0239689 - r - 0.614286 - - - - - - GridInfo - - GuidesLocked - NO - GuidesVisible - YES - HPages - 1 - ImageCounter - 1 - IsPalette - NO - Layers - - - Lock - NO - Name - Layer 1 - Print - YES - View - YES - - - LayoutInfo - - LinksVisible - NO - MagnetsVisible - NO - ModificationDate - 2005-04-17 21:58:24 -0500 - Modifier - Paul Hammant - Orientation - 2 - PageBreaks - YES - PageSetup - - BAt0eXBlZHN0cmVhbYED6IQBQISEhAtOU1ByaW50SW5mbwGEhAhOU09iamVjdACFkoSE - hBNOU011dGFibGVEaWN0aW9uYXJ5AISEDE5TRGljdGlvbmFyeQCUhAFpFJKEhIQITlNT - dHJpbmcBlIQBKxBOU0pvYkRpc3Bvc2l0aW9uhpKEmZkPTlNQcmludFNwb29sSm9ihpKE - mZkLTlNQYXBlclNpemWGkoSEhAdOU1ZhbHVlAJSEASqEhAx7X05TU2l6ZT1mZn2cgQJk - gQMYhpKEmZkZTlNQcmludFJldmVyc2VPcmllbnRhdGlvboaShISECE5TTnVtYmVyAJ2b - hJeXAIaShJmZFE5TVmVydGljYWxQYWdpbmF0aW9uhpKEoZuilwCGkoSZmRROU1ZlcnRp - Y2FsbHlDZW50ZXJlZIaShKGbopcBhpKEmZkOTlNQTVBhZ2VGb3JtYXSGkoSEhAZOU0Rh - dGEAlJeBHa2EB1s3NTk3Y108P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYt - OCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZSBDb21wdXRlci8vRFRE - IFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5 - TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+CjxkaWN0PgoJPGtleT5j - b20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUhvcml6b250YWxSZXM8L2tleT4KCTxk - aWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJ - PHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJPGtleT5j - b20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJ - PGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNSG9yaXpv - bnRhbFJlczwva2V5PgoJCQkJPHJlYWw+NzI8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBs - ZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5hcHBsZS5w - cmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp - Y2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDAzLTAxLTI0VDE2OjI4OjU0Wjwv - ZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tl - eT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJ - PC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTU9yaWVudGF0 - aW9uPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3Jl - YXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3Ry - aW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4K - CQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZv - cm1hdC5QTU9yaWVudGF0aW9uPC9rZXk+CgkJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJ - CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJPHN0 - cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNv - bS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwMy0w - MS0yNFQxNjoyODo1NFo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr - ZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2Rp - Y3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VG - b3JtYXQuUE1TY2FsaW5nPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmlu - dC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5n - bWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVt - QXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUu - cHJpbnQuUGFnZUZvcm1hdC5QTVNjYWxpbmc8L2tleT4KCQkJCTxyZWFsPjE8L3JlYWw+ - CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8 - c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+ - Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDAz - LTAxLTI0VDE2OjI4OjU0WjwvZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp - Y2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwv - ZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFn - ZUZvcm1hdC5QTVZlcnRpY2FsUmVzPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBs - ZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnBy - aW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl - dC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20u - YXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsUmVzPC9rZXk+CgkJCQk8cmVh - bD43MjwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8 - L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5n - PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJ - CTxkYXRlPjIwMDMtMDEtMjRUMTY6Mjg6NTRaPC9kYXRlPgoJCQkJPGtleT5jb20uYXBw - bGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50 - ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBs - ZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk+Cgk8ZGljdD4K - CQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJp - bmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFw - cGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0 - PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVZlcnRpY2FsU2Nh - bGluZzwva2V5PgoJCQkJPHJlYWw+MTwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnBy - aW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 - aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0 - Lm1vZERhdGU8L2tleT4KCQkJCTxkYXRlPjIwMDMtMDEtMjRUMTY6Mjg6NTRaPC9kYXRl - PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJ - CQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2Rp - Y3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5zdWJUaWNrZXQucGFwZXJfaW5mb190aWNr - ZXQ8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQu - UE1BZGp1c3RlZFBhZ2VSZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxl - LnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLnBy - aW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr - ZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+ - Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhZ2VSZWN0PC9rZXk+ - CgkJCQkJPGFycmF5PgoJCQkJCQk8cmVhbD4wLjA8L3JlYWw+CgkJCQkJCTxyZWFsPjAu - MDwvcmVhbD4KCQkJCQkJPHJlYWw+NzM0PC9yZWFsPgoJCQkJCQk8cmVhbD41NzY8L3Jl - YWw+CgkJCQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu - Y2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2Vy - PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8 - L2tleT4KCQkJCQk8ZGF0ZT4yMDA1LTA0LTE4VDAyOjQ0OjE4WjwvZGF0ZT4KCQkJCQk8 - a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGlu - dGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+ - CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFwZXJS - ZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5j - cmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwv - c3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9r - ZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50 - LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCQkJCTxhcnJheT4K - CQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJCQk8cmVhbD4tMTg8L3JlYWw+CgkJCQkJ - CTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJlYWw+NTk0PC9yZWFsPgoJCQkJCTwvYXJy - YXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJ - CQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJ - CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRh - dGU+MjAwNS0wNC0xOFQwMjo0NDoxOFo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUu - cHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVn - ZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFw - cGxlLnByaW50LlBhcGVySW5mby5QTVBhcGVyTmFtZTwva2V5PgoJCTxkaWN0PgoJCQk8 - a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5n - PmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29t - LmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJ - PGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNUGFwZXJO - YW1lPC9rZXk+CgkJCQkJPHN0cmluZz5uYS1sZXR0ZXI8L3N0cmluZz4KCQkJCQk8a2V5 - PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5j - b20uYXBwbGUucHJpbnQucG0uUG9zdFNjcmlwdDwvc3RyaW5nPgoJCQkJCTxrZXk+Y29t - LmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwMC0w - Ny0yOFQyMjo1NzowNFo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlj - a2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8 - L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50 - LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8 - a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5n - PmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29t - LmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJ - PGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1 - c3RlZFBhZ2VSZWN0PC9rZXk+CgkJCQkJPGFycmF5PgoJCQkJCQk8cmVhbD4wLjA8L3Jl - YWw+CgkJCQkJCTxyZWFsPjAuMDwvcmVhbD4KCQkJCQkJPHJlYWw+NzM0PC9yZWFsPgoJ - CQkJCQk8cmVhbD41NzY8L3JlYWw+CgkJCQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5h - cHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBw - bGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJp - bnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDAzLTAxLTI0VDE2OjI4 - OjU0WjwvZGF0ZT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVG - bGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJ - PC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZv - LlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5h - cHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBs - ZS5wcmludC5wbS5Qb3N0U2NyaXB0PC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnBy - aW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJ - CQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVy - UmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+LTE4PC9yZWFsPgoJCQkJ - CQk8cmVhbD4tMTg8L3JlYWw+CgkJCQkJCTxyZWFsPjc3NDwvcmVhbD4KCQkJCQkJPHJl - YWw+NTk0PC9yZWFsPgoJCQkJCTwvYXJyYXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJp - bnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 - aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl - dC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwMy0wMS0yNFQxNjoyODo1NFo8L2Rh - dGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5 - PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+ - CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1Q - YXBlck5hbWU8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlj - a2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnQucG0uUG9z - dFNjcmlwdDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRl - bUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+Y29tLmFw - cGxlLnByaW50LlBhcGVySW5mby5wcGQuUE1QYXBlck5hbWU8L2tleT4KCQkJCQk8c3Ry - aW5nPkxldHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tl - dC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludC5wbS5Qb3N0 - U2NyaXB0PC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1v - ZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDAwLTA3LTI4VDIyOjU3OjA0WjwvZGF0ZT4K - CQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJ - CQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8 - L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LkFQSVZlcnNpb248L2tl - eT4KCQk8c3RyaW5nPjAwLjIwPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQu - dGlja2V0LnByaXZhdGVMb2NrPC9rZXk+CgkJPGZhbHNlLz4KCQk8a2V5PmNvbS5hcHBs - ZS5wcmludC50aWNrZXQudHlwZTwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50 - LlBhcGVySW5mb1RpY2tldDwvc3RyaW5nPgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUu - cHJpbnQudGlja2V0LkFQSVZlcnNpb248L2tleT4KCTxzdHJpbmc+MDAuMjA8L3N0cmlu - Zz4KCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5wcml2YXRlTG9jazwva2V5PgoJ - PGZhbHNlLz4KCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC50eXBlPC9rZXk+Cgk8 - c3RyaW5nPmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0VGlja2V0PC9zdHJpbmc+Cjwv - ZGljdD4KPC9wbGlzdD4KhpKEmZkPTlNQcmludEFsbFBhZ2VzhpKgkoSZmQtOU1BhcGVy - TmFtZYaShJmZBkxldHRlcoaShJmZFU5TSG9yaXpvbmFsUGFnaW5hdGlvboaShKGbopcA - hpKEmZkWTlNIb3Jpem9udGFsbHlDZW50ZXJlZIaSppKEmZkJTlNQcmludGVyhpKEhIQJ - TlNQcmludGVyAJSShJmZFFRXIENoaWNhZ28gNnRoIGZsb29yhoaShJmZCE5TQ29waWVz - hpKEoZuilwGGkoSZmQ9OU1NjYWxpbmdGYWN0b3KGkoShm4SEAWahAYaShJmZDU5TUmln - aHRNYXJnaW6GkoShm7ihAIaShJmZDk5TQm90dG9tTWFyZ2luhpKEoZu4oQCGkoSZmQxO - U0xlZnRNYXJnaW6GkoShm7ihAIaShJmZC05TVG9wTWFyZ2luhpKEoZu4oQCGkoSZmQpO - U0xhc3RQYWdlhpKEoZuil4J/////hpKEmZkLTlNGaXJzdFBhZ2WGkoShm6KXAYaShJmZ - DU5TT3JpZW50YXRpb26GkoShm6KXAIaGhg== - - ReadOnly - NO - RowAlign - 1 - RowSpacing - 36 - SheetTitle - Canvas 1 - SmartAlignmentGuidesActive - YES - SmartDistanceGuidesActive - YES - UseEntirePage - - VPages - 1 - WindowInfo - - CurrentSheet - 0 - Frame - {{342, -31}, {591, 828}} - ShowRuler - - ShowStatusBar - - VisibleRegion - {{0, 0}, {576, 730}} - Zoom - 1 - - - diff --git a/tests/FunctionalTests/selenium/selenium-logo.png b/tests/FunctionalTests/selenium/selenium-logo.png deleted file mode 100644 index 1de09290..00000000 Binary files a/tests/FunctionalTests/selenium/selenium-logo.png and /dev/null differ diff --git a/tests/FunctionalTests/selenium/selenium-seleneserunner.js b/tests/FunctionalTests/selenium/selenium-seleneserunner.js deleted file mode 100644 index e1ae6f88..00000000 --- a/tests/FunctionalTests/selenium/selenium-seleneserunner.js +++ /dev/null @@ -1,172 +0,0 @@ -/* -* Copyright 2005 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -passColor = "#cfffcf"; -failColor = "#ffcfcf"; -errorColor = "#ffffff"; -workingColor = "#DEE7EC"; -doneColor = "#FFFFCC"; - -slowMode = false; - -var cmd1 = document.createElement("div"); -var cmd2 = document.createElement("div"); -var cmd3 = document.createElement("div"); -var cmd4 = document.createElement("div"); - -var postResult = "START"; - -function runTest() { - var testAppFrame = document.getElementById('myiframe'); - selenium = Selenium.createForFrame(testAppFrame); - - commandFactory = new CommandHandlerFactory(); - commandFactory.registerAll(selenium); - - testLoop = new TestLoop(commandFactory); - - testLoop.nextCommand = nextCommand; - testLoop.commandStarted = commandStarted; - testLoop.commandComplete = commandComplete; - testLoop.commandError = commandError; - testLoop.testComplete = function() {window.status = "Selenium Tests Complete, for this Test"}; - - document.getElementById("commandList").appendChild(cmd4); - document.getElementById("commandList").appendChild(cmd3); - document.getElementById("commandList").appendChild(cmd2); - document.getElementById("commandList").appendChild(cmd1); - - testLoop.start(); -} - -function nextCommand() { - - var xmlHttp = XmlHttp.create(); - - try { - alert("postResult == " + postResult); - if (postResult == "START") { - xmlHttp.open("GET", "driver?seleniumStart=true", false); - } else { - xmlHttp.open("GET", "driver?commandResult=" + postResult, false); - } - xmlHttp.send(null); - } catch(e) { - return null; - } - return extractCommand(xmlHttp); -} - -function extractCommand(xmlHttp) { - if (slowMode) { - delay(2000); - } - - var command; - try { - command = xmlHttp.responseText; - } catch (e) { - alert('could not get responseText: ' + e.message); - } - if (command.substr(0,'|testComplete'.length)=='|testComplete') { - return null; - } - - return createCommandFromWikiRow(command); -} - -function commandStarted(command) { - commandNode = document.createElement("div"); - innerHTML = command.command + '('; - if (command.target != null && command.target != "") { - innerHTML += command.target; - if (command.value != null && command.value != "") { - innerHTML += ', ' + command.value; - } - } - innerHTML += ")"; - commandNode.innerHTML = innerHTML; - commandNode.style.backgroundColor = workingColor; - document.getElementById("commandList").removeChild(cmd1); - document.getElementById("commandList").removeChild(cmd2); - document.getElementById("commandList").removeChild(cmd3); - document.getElementById("commandList").removeChild(cmd4); - cmd4 = cmd3; - cmd3 = cmd2; - cmd2 = cmd1; - cmd1 = commandNode; - document.getElementById("commandList").appendChild(cmd4); - document.getElementById("commandList").appendChild(cmd3); - document.getElementById("commandList").appendChild(cmd2); - document.getElementById("commandList").appendChild(cmd1); -} - -function commandComplete(result) { - if (result.failed) { - postResult = result.failureMessage; - commandNode.title = result.failureMessage; - commandNode.style.backgroundColor = failColor; - } else if (result.passed) { - postResult = "PASSED"; - commandNode.style.backgroundColor = passColor; - } else { - postResult = result.result; - commandNode.style.backgroundColor = doneColor; - } -} - -function commandError(message) { - postResult = "ERROR"; - commandNode.style.backgroundColor = errorColor; - commandNode.title = message; -} - -function slowClicked() { - slowMode = !slowMode; -} - -function delay(millis) { - startMillis = new Date(); - while (true) { - milli = new Date(); - if (milli-startMillis > millis) { - break; - } - } -} - -function getIframeDocument(iframe) { - if (iframe.contentDocument) { - return iframe.contentDocument; - } - else { - return iframe.contentWindow.document; - } -} - -// Parses a Wiki table row into a Javascript expression -function createCommandFromWikiRow(wikiRow) { - var tokens; - if(tokens = wikiRow.trim().match(/^\|([^\|]*)\|([^\|]*)\|([^\|]*)\|$/m)) { - var functionName = tokens[1].trim(); - var arg1 = tokens[2].trim(); - var arg2 = tokens[3].trim(); - return new SeleniumCommand(functionName, arg1, arg2); - } else { - throw new Error("Bad wiki row format:" + wikiRow); - } -} diff --git a/tests/FunctionalTests/selenium/selenium-tableparser.js b/tests/FunctionalTests/selenium/selenium-tableparser.js deleted file mode 100644 index 2cc0ff9b..00000000 --- a/tests/FunctionalTests/selenium/selenium-tableparser.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2004 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -TableParser = function(wikiTableRows) { - this.wikiTableRows = wikiTableRows; -}; - -// Parses a Wiki table row into a SeleniumB Javascript expression -TableParser.prototype.createCommandFromWikiRow = function(wikiRow) { - var tokens; - if(tokens = wikiRow.trim().match(/^\|([^\|]*)\|([^\|]*)\|([^\|]*)\|$/m)) { - var functionName = tokens[1].trim(); - var arg1 = tokens[2].trim(); - var arg2 = tokens[3].trim(); - return new SeleniumCommand(functionName, arg1, arg2); - } else { - throw new Error("Bad wiki row format:" + wikiRow); - } -}; - -// Parses a HTML table row into a SeleniumB Javascript expression -TableParser.prototype.createCommandFromHtmlRow = function(row) { - if(row.cells.length != 3) { - throw new Error("Bad HTML row format. Rows must have 3 coumns, but had " + row.cells.length); - } - var functionName = getText(row.cells[0]); - var arg1 = getText(row.cells[1]); - var arg2 = getText(row.cells[2]); - return new SeleniumCommand(functionName, arg1, arg2); -}; - -TableParser.prototype.loop = function() { - row = this.wikiTableRows.getRow(); - if (row == null) return null; - return this.createCommandForRow(row); -}; \ No newline at end of file diff --git a/tests/FunctionalTests/selenium/selenium-testrunner.js b/tests/FunctionalTests/selenium/selenium-testrunner.js deleted file mode 100644 index e786b29b..00000000 --- a/tests/FunctionalTests/selenium/selenium-testrunner.js +++ /dev/null @@ -1,597 +0,0 @@ -/* -* Copyright 2004 ThoughtWorks, Inc -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -*/ - -// The current row in the list of tests (test suite) -currentRowInSuite = 0; - -// Where are we at in the current test -testTableRows = null; -currentRowInTest = -1; -currentCommandRow = null; - -// Whether or not the jsFT should run all tests in the suite -runAllTests = false; - -// Whether or not the current test has any errors; -testFailed = false; -suiteFailed = false; - -// Colors used to provide feedback -passColor = "#ccffcc"; -doneColor = "#eeffee"; -failColor = "#ffcccc"; -workingColor = "#ffffcc"; - -// Holds the handlers for each command. -commandHandlers = null; - -// The number of tests run -numTestPasses = 0; - -// The number of tests that have failed -numTestFailures = 0; - -// The number of commands which have passed -numCommandPasses = 0; - -// The number of commands which have failed -numCommandFailures = 0; - -// The number of commands which have caused errors (element not found) -numCommandErrors = 0; - -// The time that the test was started. -startTime = null; - -// The current time. -currentTime = null; - -// An simple enum for failureType -ERROR = 0; -FAILURE = 1; - -runInterval = 0; - -function setRunInterval() { - // Get the value of the checked runMode option. - // There should be a way of getting the value of the "group", but I don't know how. - var runModeOptions = document.forms['controlPanel'].runMode; - for (var i = 0; i < runModeOptions.length; i++) { - if (runModeOptions[i].checked) { - runInterval = runModeOptions[i].value; - break; - } - } -} - -function continueCurrentTest() { - document.getElementById('continueTest').disabled = true; - testLoop.resume(); -} - -function getApplicationFrame() { - return document.getElementById('myiframe'); -} - -function getSuiteFrame() { - return document.getElementById('testSuiteFrame'); -} - -function getTestFrame(){ - return document.getElementById('testFrame'); -} - -function loadAndRunIfAuto() { - loadSuiteFrame(); -} - -function start() { - setRunInterval(); - loadSuiteFrame(); -} - -function loadSuiteFrame() { - var testAppFrame = document.getElementById('myiframe'); - selenium = Selenium.createForFrame(testAppFrame); - registerCommandHandlers(); - - //set the runInterval if there is a queryParameter for it - var tempRunInterval = getQueryParameter("runInterval"); - if (tempRunInterval) { - runInterval = tempRunInterval; - } - - document.getElementById("modeRun").onclick = setRunInterval; - document.getElementById('modeWalk').onclick = setRunInterval; - document.getElementById('modeStep').onclick = setRunInterval; - document.getElementById('continueTest').onclick = continueCurrentTest; - - var testSuiteName = getQueryParameter("test"); - - if (testSuiteName) { - addLoadListener(getSuiteFrame(), onloadTestSuite); - getSuiteFrame().src = testSuiteName; - } else { - onloadTestSuite(); - } -} - -function startSingleTest() { - removeLoadListener(getApplicationFrame(), startSingleTest); - var singleTestName = getQueryParameter("singletest"); - addLoadListener(getTestFrame(), startTest); - getTestFrame().src = singleTestName; -} - -function getIframeDocument(iframe) -{ - if (iframe.contentDocument) { - return iframe.contentDocument; - } - else { - return iframe.contentWindow.document; - } -} - -function onloadTestSuite() { - removeLoadListener(getSuiteFrame(), onloadTestSuite); - suiteTable = getIframeDocument(getSuiteFrame()).getElementsByTagName("table")[0]; - - // Add an onclick function to each link in the suite table - for(rowNum = 1;rowNum < suiteTable.rows.length; rowNum++) { - addOnclick(suiteTable, rowNum); - } - - - if (isAutomatedRun()) { - startTestSuite(); - } else if (getQueryParameter("autoURL")) { - - addLoadListener(getApplicationFrame(), startSingleTest); - - getApplicationFrame().src = getQueryParameter("autoURL"); - - } else { - testLink = suiteTable.rows[currentRowInSuite+1].cells[0].getElementsByTagName("a")[0]; - getTestFrame().src = testLink.href; - } -} - -// Adds an onclick function to the link in the given row in suite table. -// This function checks whether the test has already been run and the data is -// stored. If the data is stored, it sets the test frame to be the stored data. -// Otherwise, it loads the fresh page. -function addOnclick(suiteTable, rowNum) { - aLink = suiteTable.rows[rowNum].cells[0].getElementsByTagName("a")[0]; - aLink.onclick = function(eventObj) { - srcObj = null; - - // For mozilla-like browsers - if(eventObj) - srcObj = eventObj.target; - - // For IE-like browsers - else if (getSuiteFrame().contentWindow.event) - srcObj = getSuiteFrame().contentWindow.event.srcElement; - - // The target row (the event source is not consistently reported by browsers) - row = srcObj.parentNode.parentNode.rowIndex || srcObj.parentNode.parentNode.parentNode.rowIndex; - - // If the row has a stored results table, use that - if(suiteTable.rows[row].cells[1]) { - var bodyElement = getIframeDocument(getTestFrame()).body; - - // Create a div element to hold the results table. - var tableNode = getIframeDocument(getTestFrame()).createElement("div"); - var resultsCell = suiteTable.rows[row].cells[1]; - tableNode.innerHTML = resultsCell.innerHTML; - - // Append this text node, and remove all the preceding nodes. - bodyElement.appendChild(tableNode); - while (bodyElement.firstChild != bodyElement.lastChild) { - bodyElement.removeChild(bodyElement.firstChild); - } - } - // Otherwise, just open up the fresh page. - else { - getTestFrame().src = suiteTable.rows[row].cells[0].getElementsByTagName("a")[0].href; - } - - return false; - }; -} - -function isQueryParameterTrue(name) { - parameterValue = getQueryParameter(name); - return (parameterValue != null && parameterValue.toLowerCase() == "true"); -} - -function getQueryParameter(searchKey) { - var clauses = location.search.substr(1).split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=',2); - var key = unescape(keyValuePair[0]); - if (key == searchKey) { - return unescape(keyValuePair[1]); - } - } - return null; -} - -function isNewWindow() { - return isQueryParameterTrue("newWindow"); -} - -function isAutomatedRun() { - return isQueryParameterTrue("auto"); -} - -function resetMetrics() { - numTestPasses = 0; - numTestFailures = 0; - numCommandPasses = 0; - numCommandFailures = 0; - numCommandErrors = 0; - startTime = new Date().getTime(); -} - -function runSingleTest() { - runAllTests = false; - resetMetrics(); - startTest(); -} - -function startTest() { - removeLoadListener(getTestFrame(), startTest); - - // Scroll to the top of the test frame - if (getTestFrame().contentWindow) { - getTestFrame().contentWindow.scrollTo(0,0); - } - else { - frames['testFrame'].scrollTo(0,0); - } - - testTable = getIframeDocument(getTestFrame()).getElementsByTagName("table")[0]; - testTableRows = testTable.rows; - currentRowInTest = -1; - currentCommandRow = null; - - testFailed = false; - storedVars = new Object(); - - resetTestTable(); - - testLoop = initialiseTestLoop(); - testLoop.start(); -} - -function resetTestTable() { - for (var i = 0; i <= testTableRows.length - 1; i++) { - testTableRows[i].bgColor = "white"; - } -} - -function startTestSuite() { - resetMetrics(); - currentRowInSuite = 0; - runAllTests = true; - suiteFailed = false; - - runNextTest(); -} - -function runNextTest() { - if (!runAllTests) - return; - - suiteTable = getIframeDocument(getSuiteFrame()).getElementsByTagName("table")[0]; - - // Do not change the row color of the first row - if (currentRowInSuite > 0) { - // Provide test-status feedback - if (testFailed) { - setCellColor(suiteTable.rows, currentRowInSuite, 0, failColor); - } else { - setCellColor(suiteTable.rows, currentRowInSuite, 0, passColor); - } - - // Set the results from the previous test run - setResultsData(suiteTable, currentRowInSuite); - } - - currentRowInSuite++; - - // If we are done with all of the tests, set the title bar as pass or fail - if (currentRowInSuite >= suiteTable.rows.length) { - if (suiteFailed) { - setCellColor(suiteTable.rows, 0, 0, failColor); - } else { - setCellColor(suiteTable.rows, 0, 0, passColor); - } - - // If this is an automated run (i.e., build script), then submit - // the test results by posting to a form - if (isAutomatedRun()) - postTestResults(suiteFailed, suiteTable); - } - - else { - // Make the current row blue - setCellColor(suiteTable.rows, currentRowInSuite, 0, workingColor); - - testLink = suiteTable.rows[currentRowInSuite].cells[0].getElementsByTagName("a")[0]; - testLink.focus(); - - var testFrame = getTestFrame(); - addLoadListener(testFrame, startTest); - - selenium.browserbot.setIFrameLocation(testFrame, testLink.href); - } -} - -function setCellColor(tableRows, row, col, colorStr) { - tableRows[row].cells[col].bgColor = colorStr; -} - -// Sets the results from a test into a hidden column on the suite table. So, -// for each tests, the second column is set to the HTML from the test table. -function setResultsData(suiteTable, row) { - // Create a text node of the test table - var resultTable = getIframeDocument(getTestFrame()).body.innerHTML; - if (!resultTable) return; - - var tableNode = suiteTable.ownerDocument.createElement("div"); - tableNode.innerHTML = resultTable; - - var new_column = suiteTable.ownerDocument.createElement("td"); - new_column.appendChild(tableNode); - - // Set the column to be invisible - new_column.style.cssText = "display: none;"; - - // Add the invisible column - suiteTable.rows[row].appendChild(new_column); -} - -// Post the results to a servlet, CGI-script, etc. The URL of the -// results-handler defaults to "/postResults", but an alternative location -// can be specified by providing a "resultsUrl" query parameter. -// -// Parameters passed to the results-handler are: -// result: passed/failed depending on whether the suite passed or failed -// totalTime: the total running time in seconds for the suite. -// -// numTestPasses: the total number of tests which passed. -// numTestFailures: the total number of tests which failed. -// -// numCommandPasses: the total number of commands which passed. -// numCommandFailures: the total number of commands which failed. -// numCommandErrors: the total number of commands which errored. -// -// suite: the suite table, including the hidden column of test results -// testTable.1 to testTable.N: the individual test tables -// -function postTestResults(suiteFailed, suiteTable) { - - form = document.createElement("form"); - document.body.appendChild(form); - - form.id = "resultsForm"; - form.method="post"; - form.target="myiframe"; - - var resultsUrl = getQueryParameter("resultsUrl"); - if (!resultsUrl) { - resultsUrl = "./postResults"; - } - - var actionAndParameters = resultsUrl.split('?',2); - form.action = actionAndParameters[0]; - var resultsUrlQueryString = actionAndParameters[1]; - - form.createHiddenField = function(name, value) { - input = document.createElement("input"); - input.type = "hidden"; - input.name = name; - input.value = value; - this.appendChild(input); - }; - - if (resultsUrlQueryString) { - var clauses = resultsUrlQueryString.split('&'); - for (var i = 0; i < clauses.length; i++) { - var keyValuePair = clauses[i].split('=',2); - var key = unescape(keyValuePair[0]); - var value = unescape(keyValuePair[1]); - form.createHiddenField(key, value); - } - } - - form.createHiddenField("result", suiteFailed == true ? "failed" : "passed"); - - form.createHiddenField("totalTime", Math.floor((currentTime - startTime) / 1000)); - form.createHiddenField("numTestPasses", numTestPasses); - form.createHiddenField("numTestFailures", numTestFailures); - form.createHiddenField("numCommandPasses", numCommandPasses); - form.createHiddenField("numCommandFailures", numCommandFailures); - form.createHiddenField("numCommandErrors", numCommandErrors); - - // Create an input for each test table. The inputs are named - // testTable.1, testTable.2, etc. - for (rowNum = 1; rowNum < suiteTable.rows.length;rowNum++) { - // If there is a second column, then add a new input - if (suiteTable.rows[rowNum].cells.length > 1) { - var resultCell = suiteTable.rows[rowNum].cells[1]; - form.createHiddenField("testTable." + rowNum, resultCell.innerHTML); - // remove the resultCell, so it's not included in the suite HTML - resultCell.parentNode.removeChild(resultCell); - } - } - - // Add HTML for the suite itself - form.createHiddenField("suite", suiteTable.parentNode.innerHTML); - - form.submit(); - document.body.removeChild(form); - -} - -function printMetrics() { - setText(document.getElementById("commandPasses"), numCommandPasses); - setText(document.getElementById("commandFailures"), numCommandFailures); - setText(document.getElementById("commandErrors"), numCommandErrors); - setText(document.getElementById("testRuns"), numTestPasses + numTestFailures); - setText(document.getElementById("testFailures"), numTestFailures); - - currentTime = new Date().getTime(); - - timeDiff = currentTime - startTime; - totalSecs = Math.floor(timeDiff / 1000); - - minutes = Math.floor(totalSecs / 60); - seconds = totalSecs % 60; - - setText(document.getElementById("elapsedTime"), pad(minutes)+":"+pad(seconds)); -} - -// Puts a leading 0 on num if it is less than 10 -function pad (num) { - return (num > 9) ? num : "0" + num; -} - -/* - * Register all of the built-in command handlers with the CommandHandlerFactory. - * TODO work out an easy way for people to register handlers without modifying the Selenium sources. - */ -function registerCommandHandlers() { - commandFactory = new CommandHandlerFactory(); - commandFactory.registerAll(selenium); - -} - -function initialiseTestLoop() { - testLoop = new TestLoop(commandFactory); - - testLoop.getCommandInterval = function() { return runInterval; }; - testLoop.nextCommand = nextCommand; - testLoop.commandStarted = commandStarted; - testLoop.commandComplete = commandComplete; - testLoop.commandError = commandError; - testLoop.testComplete = testComplete; - testLoop.pause = function() { - document.getElementById('continueTest').disabled = false; - }; - return testLoop; -} - -function findNextCommandRow() { - // Return the next row with >= 3 cells - while (currentRowInTest < testTableRows.length - 1) { - currentRowInTest++; - currentCommandRow = testTableRows[currentRowInTest]; - if (currentCommandRow.cells.length >= 3) { - return; - } - } - currentCommandRow = null; -} - -function nextCommand() { - findNextCommandRow(); - if (currentCommandRow == null) { - return null; - } - var row = currentCommandRow; - if (! row.cachedValue) { - row.cachedValue = removeNbsp(getText(row.cells[2])); - } - return new SeleniumCommand(getText(row.cells[0]), - getText(row.cells[1]), - row.cachedValue); -} - -function removeNbsp(value) { - return value.replace(/\240/g, ""); -} - -function scrollIntoView(element) { - if (element.scrollIntoView) { - element.scrollIntoView(false); - return; - } - // TODO: work out how to scroll browsers that don't support - // scrollIntoView (like Konqueror) -} - -function commandStarted() { - currentCommandRow.bgColor = workingColor; - scrollIntoView(currentCommandRow.cells[0]); - printMetrics(); -} - -function commandComplete(result) { - if (result.failed) { - numCommandFailures += 1; - recordFailure(result.failureMessage); - } else if (result.passed) { - numCommandPasses += 1; - currentCommandRow.bgColor = passColor; - } else { - currentCommandRow.bgColor = doneColor; - } -} - -function commandError(errorMessage) { - numCommandErrors += 1; - recordFailure(errorMessage); -} - -function recordFailure(errorMsg) { - // Set cell background to red - currentCommandRow.bgColor = failColor; - - // Set error message - currentCommandRow.cells[2].innerHTML = errorMsg; - currentCommandRow.title = errorMsg; - testFailed = true; - suiteFailed = true; -} - -function testComplete() { - if(testFailed) { - testTableRows[0].bgColor = failColor; - numTestFailures += 1; - } - else { - testTableRows[0].bgColor = passColor; - numTestPasses += 1; - } - - printMetrics(); - - window.setTimeout("runNextTest()", 1); -} - -Selenium.prototype.doPause = function(waitTime) { - testLoop.pauseInterval = waitTime; -}; - -Selenium.prototype.doBreak = function() { - document.getElementById('modeStep').checked = true; - runInterval = -1; -}; diff --git a/tests/FunctionalTests/selenium/selenium.css b/tests/FunctionalTests/selenium/selenium.css deleted file mode 100644 index 6e9f3f30..00000000 --- a/tests/FunctionalTests/selenium/selenium.css +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2005 ThoughtWorks, Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*---( Layout )---*/ - -body { - margin: 0; - padding: 0; - overflow: auto; -} - -td { - position: static; -} - -tr { - vertical-align: top; -} - -.layout { - width: 100%; - height: 100%; - border-collapse: collapse; -} - -.layout td { - margin: 0; - padding: 0; - border: 0; -} - -iframe { - width: 100%; - height: 100%; - border: 0; - background: white; - overflow: auto; -} - -/*---( Style )---*/ - -body, html { - font-family: Verdana, Arial, sans-serif; -} - -.selenium th, .selenium td { - border: 1px solid #999; -} - -.header { - background: #ccc; - padding: 0; - font-size: 90%; -} - -#controlPanel { - padding: 0.5ex; - background: #eee; - overflow: auto; - font-size: 75%; - text-align: center; -} - -#controlPanel fieldset { - margin: 0.3ex; - padding: 0.3ex; -} - -#controlPanel fieldset legend { - color: black; -} - -#controlPanel button { - margin: 0.5ex; -} - -#controlPanel table { - font-size: 100%; -} - -#controlPanel th, #controlPanel td { - border: 0; -} - -h1 { - margin: 0.2ex; - font-size: 130%; - font-weight: bold; -} - -h2 { - margin: 0.2ex; - font-size: 80%; - font-weight: normal; -} - -.selenium a { - color: black; - text-decoration: none; -} - -.selenium a:hover { - text-decoration: underline; -} - -button, label { - cursor: pointer; -} - -#stats { - margin: 0.5em auto 0.5em auto; -} - -#stats th, #stats td { - text-align: left; - padding-left: 2px; -} - -#stats th { - text-decoration: underline; -} - -#stats td.count { - font-weight: bold; - text-align: right; -} - -#testRuns { - color: green; -} - -#testFailures { - color: red; -} - -#commandPasses { - color: green; -} - -#commandFailures { - color: red; -} - -#commandErrors { - color: #f90; -} - -.splash { - border: 1px solid black; - padding: 20px; - background: #ccc; -} - -/*---( Logging Console )---*/ - -#logging-console { - background: #fff; - font-size: 75%; -} - -#logging-console #banner { - display: block; - width: 100%; - position: fixed; - top: 0; - background: #ddd; - border-bottom: 1px solid #666; -} - -#logging-console #logLevelChooser { - float: right; - margin: 3px; -} - -#logging-console ul { - list-style-type: none; - margin: 0px; - margin-top: 3em; - padding-left: 5px; -} - -#logging-console li { - margin: 2px; - border-top: 1px solid #ccc; -} - -#logging-console li.error { - font-weight: bold; - color: red; -} - -#logging-console li.warn { - color: red; -} - -#logging-console li.debug { - color: green; -} diff --git a/tests/FunctionalTests/selenium/user-extensions.js.sample b/tests/FunctionalTests/selenium/user-extensions.js.sample deleted file mode 100644 index f234c29e..00000000 --- a/tests/FunctionalTests/selenium/user-extensions.js.sample +++ /dev/null @@ -1,62 +0,0 @@ -/* - * By default, Selenium looks for a file called "user-extensions.js", and loads and javascript - * code found in that file. This file is a sample of what that file could look like. - * - * user-extensions.js provides a convenient location for adding extensions to Selenium, like - * new actions, checks and locator-strategies. - * By default, 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. - */ - -// The following examples try to give an indication of how Selenium can be extended with javascript. - -// All do* methods on the Selenium prototype are added as actions. -// Eg add a typeRepeated action to Selenium, which types the text twice into a text box. -// The typeTwiceAndWait command will be available automatically -Selenium.prototype.doTypeRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to type - var valueToType = text + text; - - // Replace the element text with the new text - this.page().replaceText(element, valueToType); -}; - -// All assert* methods on the Selenium prototype are added as checks. -// Eg add a assertValueRepeated check, that makes sure that the element value -// consists of the supplied text repeated. -// The verify version will be available automatically. -Selenium.prototype.assertValueRepeated = function(locator, text) { - // All locator-strategies are automatically handled by "findElement" - var element = this.page().findElement(locator); - - // Create the text to verify - var expectedValue = text + text; - - // Get the actual element value - var actualValue = element.value; - - // Make sure the actual value matches the expected - this.assertMatches(expectedValue, actualValue); -}; - -// All locateElementBy* methods are added as locator-strategies. -// Eg add a "valuerepeated=" locator, that finds the first element with the supplied value, repeated. -// The "inDocument" is a the document you are searching. -PageBot.prototype.locateElementByValueRepeated = function(text, inDocument) { - // Create the text to search for - var expectedValue = text + text; - - // Loop through all elements, looking for ones that have a value === our expected value - var allElements = inDocument.getElementsByTagName("*"); - for (var i = 0; i < allElements.length; i++) { - var testElement = allElements[i]; - if (testElement.value && testElement.value === expectedValue) { - return testElement; - } - } - return null; -}; diff --git a/tests/FunctionalTests/selenium/xmlextras.js b/tests/FunctionalTests/selenium/xmlextras.js deleted file mode 100644 index 267aa058..00000000 --- a/tests/FunctionalTests/selenium/xmlextras.js +++ /dev/null @@ -1,153 +0,0 @@ -// This is a third party JavaScript library from -// http://webfx.eae.net/dhtml/xmlextras/xmlextras.html -// i.e. This has not been written by ThoughtWorks. - -//