├── parallelwebdriver ├── settings.gradle ├── .settings │ ├── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs │ └── org.eclipse.jdt.core.prefs ├── .project ├── README.md ├── src │ ├── test │ │ ├── resources │ │ │ └── logback.xml │ │ └── java │ │ │ └── webdriver │ │ │ └── test │ │ │ ├── TestFrames.java │ │ │ ├── TestHandleCacheTwo.java │ │ │ ├── TestHandleCacheThree.java │ │ │ └── TestHandleCacheOne.java │ └── main │ │ └── java │ │ └── webdriver │ │ └── test │ │ ├── MainPage.java │ │ ├── IFrame2.java │ │ └── IFrame1.java ├── build.gradle └── .classpath ├── settings.gradle ├── google ├── src │ ├── test │ │ ├── resources │ │ │ ├── testdata1.csv │ │ │ ├── testdata2.csv │ │ │ └── logback.xml │ │ └── java │ │ │ └── qa │ │ │ └── webdriver │ │ │ └── tests │ │ │ ├── DataProviderTest.java │ │ │ ├── GoogleTest1.java │ │ │ └── GoogleTest2.java │ └── main │ │ └── java │ │ └── qa │ │ └── webdriver │ │ └── util │ │ └── GoogleSearchPage.java ├── .settings │ ├── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs │ └── org.eclipse.jdt.core.prefs ├── .project ├── build.gradle └── .classpath ├── commonlib ├── .settings │ ├── gradle │ │ ├── org.springsource.ide.eclipse.gradle.core.prefs │ │ └── org.springsource.ide.eclipse.gradle.refresh.prefs │ └── org.eclipse.jdt.core.prefs ├── .project ├── build.gradle ├── src │ └── main │ │ ├── resources │ │ └── logback.xml │ │ └── java │ │ └── qa │ │ └── webdriver │ │ └── util │ │ ├── CoreUtils.java │ │ └── WebDriverUtils.java └── .classpath ├── LICENSE ├── clean.bat ├── membrane_proxy_config.xml ├── hubConfig.json ├── hubConfigLinux.json ├── .gitattributes ├── node1ConfigLinux.json ├── gradle-app.setting ├── node1Config.json ├── startWebDriverGridHub.sh ├── startWebDriverGridHub.bat ├── .project ├── startWebDriverGridNode.sh ├── startWebDriverGridNode.bat ├── .gitignore ├── runProjectMenu.bat └── README.md /parallelwebdriver/settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include "commonlib", "google", "parallelwebdriver" 2 | 3 | -------------------------------------------------------------------------------- /google/src/test/resources/testdata1.csv: -------------------------------------------------------------------------------- 1 | test1,apple computer,history 2 | test2,android app,development 3 | test3,iphone app,development 4 | test4,java programming,tutorial 5 | -------------------------------------------------------------------------------- /google/src/test/resources/testdata2.csv: -------------------------------------------------------------------------------- 1 | test5,gradle user,guide pdf 2 | test6,groovy script,parameters 3 | test7,xtend language,documentation 4 | test8,javascript,substring 5 | -------------------------------------------------------------------------------- /google/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Apr 03 15:30:44 PDT 2013 3 | org.springsource.ide.eclipse.gradle.linkedresources= 4 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 5 | -------------------------------------------------------------------------------- /commonlib/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Apr 03 15:30:44 PDT 2013 3 | org.springsource.ide.eclipse.gradle.linkedresources= 4 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 5 | -------------------------------------------------------------------------------- /parallelwebdriver/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences 2 | #Wed Apr 03 15:30:44 PDT 2013 3 | org.springsource.ide.eclipse.gradle.linkedresources= 4 | org.springsource.ide.eclipse.gradle.rootprojectloc=.. 5 | -------------------------------------------------------------------------------- /google/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Wed Apr 03 15:30:55 PDT 2013 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=true 7 | enableBeforeTasks=false 8 | enableDSLD=false 9 | useHierarchicalNames=false 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Academic Free License ("AFL") v. 3.0 2 | 3 | This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work: 4 | 5 | Licensed under the Academic Free License version 3.0 6 | 7 | http://opensource.org/licenses/afl-3.0.php 8 | -------------------------------------------------------------------------------- /commonlib/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Wed Apr 03 15:30:54 PDT 2013 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=true 7 | enableBeforeTasks=false 8 | enableDSLD=false 9 | useHierarchicalNames=false 10 | -------------------------------------------------------------------------------- /parallelwebdriver/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs: -------------------------------------------------------------------------------- 1 | #org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences 2 | #Wed Apr 03 15:30:55 PDT 2013 3 | addResourceFilters=true 4 | afterTasks=afterEclipseImport; 5 | beforeTasks=cleanEclipse;eclipse; 6 | enableAfterTasks=true 7 | enableBeforeTasks=false 8 | enableDSLD=false 9 | useHierarchicalNames=false 10 | -------------------------------------------------------------------------------- /google/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | google 4 | 5 | 6 | 7 | org.eclipse.jdt.core.javanature 8 | 9 | 10 | 11 | org.eclipse.jdt.core.javabuilder 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /commonlib/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | commonlib 4 | 5 | 6 | 7 | org.eclipse.jdt.core.javanature 8 | 9 | 10 | 11 | org.eclipse.jdt.core.javabuilder 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 3 | :: This script cleans unused WebDriver temp files from your computer 4 | ECHO Cleaning Temp\webdriver*... 5 | for /d %%a in ( %USERPROFILE%\AppData\Local\Temp\webdriver* ) do rmdir /s /q %%a 6 | ECHO Temp\*webdriver-profile... 7 | for /d %%a in ( %USERPROFILE%\AppData\Local\Temp\*webdriver-profile ) do rmdir /s /q %%a 8 | ECHO Clean script is finished. 9 | pause 10 | -------------------------------------------------------------------------------- /parallelwebdriver/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | parallelwebdriver 4 | 5 | 6 | 7 | org.eclipse.jdt.core.javanature 8 | 9 | 10 | 11 | org.eclipse.jdt.core.javabuilder 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /membrane_proxy_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 127.0.0.1 6 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /hubConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment" : "This is the configuration for grid hub.", 3 | "host": ip, 4 | "maxSessions": 11, 5 | "port": 4444, 6 | "cleanupCycle": 5000, 7 | "timeout": 300000, 8 | "newSessionWaitTimeout": -1, 9 | "servlets": [], 10 | "prioritizer": null, 11 | "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", 12 | "throwOnCapabilityNotPresent": true, 13 | "nodePolling": 180000, 14 | "platform": "WINDOWS" 15 | } 16 | -------------------------------------------------------------------------------- /hubConfigLinux.json: -------------------------------------------------------------------------------- 1 | { 2 | "_comment" : "This is configuration for the grid hub on Linux.", 3 | "host": ip, 4 | "maxSessions": 11, 5 | "port": 4444, 6 | "cleanupCycle": 5000, 7 | "timeout": 300000, 8 | "newSessionWaitTimeout": -1, 9 | "servlets": [], 10 | "prioritizer": null, 11 | "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", 12 | "throwOnCapabilityNotPresent": true, 13 | "nodePolling": 180000, 14 | "platform": "LINUX" 15 | } 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /google/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | # 2 | #Thu Aug 01 07:59:59 PDT 2013 3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 10 | eclipse.preferences.version=1 11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 14 | -------------------------------------------------------------------------------- /commonlib/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | # 2 | #Thu Aug 01 07:59:59 PDT 2013 3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 10 | eclipse.preferences.version=1 11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 14 | -------------------------------------------------------------------------------- /parallelwebdriver/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | # 2 | #Thu Aug 01 07:59:59 PDT 2013 3 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 4 | org.eclipse.jdt.core.compiler.compliance=1.7 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 7 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 8 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 9 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 10 | eclipse.preferences.version=1 11 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 12 | org.eclipse.jdt.core.compiler.source=1.7 13 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 14 | -------------------------------------------------------------------------------- /commonlib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | //apply plugin: 'idea' 3 | apply plugin: 'eclipse' 4 | group = 'selenium.webdriver.qa' 5 | 6 | ext { 7 | projTitle = 'WebDriver Common Lib' 8 | projVersion = '1.0' 9 | } 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+' 17 | compile group: 'org.seleniumhq.selenium', name: 'selenium-server', version: '2.+' 18 | compile group: 'junit', name: 'junit', version: '4.+' 19 | compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.+' 20 | compile group: 'ch.qos.logback', name: 'logback-core', version: '1.0.+' 21 | compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.0.+' 22 | } 23 | 24 | -------------------------------------------------------------------------------- /parallelwebdriver/README.md: -------------------------------------------------------------------------------- 1 | #Sample project for WebDriver handling multiple windows 2 | =========================== 3 | 4 | Example of different methods of handling popup windows with Selenium WebDriver. If you would like 5 | to add your own method, fork my code and then send me a "pull request" and I will review it and 6 | add it. 7 | 8 | ##Running this project 9 | 10 | 1. You need to first start the web HTTP server located at: 11 | [http://djangofan.github.com/html-test-site/](http://djangofan.github.com/html-test-site/) 12 | 13 | NOTE: You could instead configure the build.gradle to point to the direct GitHub URL at:
14 | http://djangofan.github.com/html-test-site/site/index.html 15 | 16 | 2. Then, start the Grid Hub and the Grid Node that are contained at: 17 | https://github.com/djangofan/WebDriverTestingTemplate/ 18 | 19 | 20 | -------------------------------------------------------------------------------- /parallelwebdriver/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %-4relative [%thread] %-5level %logger{35} - %msg %n 8 | 9 | 10 | 11 | 12 | build/parallelwebdriver.log 13 | false 14 | 16 | 17 | %-4r %-5level %logger{35}: %msg%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /node1ConfigLinux.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": 3 | [ 4 | { 5 | "browserName": "firefox", 6 | "acceptSslCerts": true, 7 | "javascriptEnabled": true, 8 | "takesScreenshot": false, 9 | "firefox_profile": "", 10 | "browser-version": "23.0.1", 11 | "platform": "LINUX", 12 | "maxInstances": 5 13 | }, 14 | { 15 | "browserName": "chrome", 16 | "maxInstances": 5, 17 | "platform": "LINUX" 18 | } 19 | ], 20 | "configuration": 21 | { 22 | "_comment" : "This is configuration for the grid node 1 on Linux.", 23 | "cleanUpCycle": 2000, 24 | "timeout": 30000, 25 | "port": 5555, 26 | "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", 27 | "host": ip, 28 | "register": true, 29 | "hubPort": 4444, 30 | "maxSessions": 5 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gradle-app.setting: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /node1Config.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": 3 | [ 4 | { 5 | "browserName": "firefox", 6 | "acceptSslCerts": true, 7 | "javascriptEnabled": true, 8 | "takesScreenshot": false, 9 | "firefox_profile": "", 10 | "browser-version": "23.0.1", 11 | "platform": "WINDOWS", 12 | "maxInstances": 5 13 | }, 14 | { 15 | "browserName": "chrome", 16 | "maxInstances": 5, 17 | "platform": "WINDOWS" 18 | }, 19 | { 20 | "browserName": "internetExplorer", 21 | "maxInstances": 1, 22 | "platform": "WINDOWS" 23 | } 24 | ], 25 | "configuration": 26 | { 27 | "_comment" : "This is configuration for the grid node 1.", 28 | "cleanUpCycle": 2000, 29 | "timeout": 30000, 30 | "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", 31 | "port": 5555, 32 | "host": ip, 33 | "register": true, 34 | "hubPort": 4444, 35 | "maxSessions": 5 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /google/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %-4relative [%thread] %-5level %logger{35} - %msg %n 8 | 9 | 10 | 11 | 12 | build/google.log 13 | false 14 | 16 | 17 | %-4r %-5level %logger{35}: %msg%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /startWebDriverGridHub.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "WebDriver Grid Hub on 4444" 4 | echo "" 5 | 6 | echo "*********************************************" 7 | echo "*" 8 | echo "* WebDriver grid Hub instance." 9 | echo "*" 10 | echo "* http://localhost:4444/grid/console" 11 | echo "*" 12 | echo "*********************************************" 13 | echo "" 14 | 15 | jarfile="selenium-server-standalone-2.35.0.jar" 16 | wgetbin="/usr/bin/wget" 17 | 18 | if [ -z "${JAVA_HOME+xxx}" ]; then 19 | echo JAVA_HOME is not set at all; 20 | exit 1 21 | fi 22 | 23 | echo $jarfile 24 | echo $wgetbin 25 | echo $JAVA_HOME 26 | export PATH="$JAVA_HOME/bin:$PATH" 27 | echo $PATH 28 | 29 | if [ ! -f $jarfile ]; then 30 | echo "Jar file not found!" 31 | if [ -f $wgetbin ]; then 32 | echo "Wget binary is found!" 33 | echo "Downloading Selenium standalone .jar file..." 34 | echo "" 35 | $wgetbin --dot-style=binary http://selenium.googlecode.com/files/$jarfile 36 | else 37 | echo "Wget.exe is missing." 38 | echo "" 39 | exit 1 40 | fi 41 | fi 42 | 43 | $JAVA_HOME/bin/java -jar $jarfile -role hub -hubConfig ./hubConfig.json -debug 44 | -------------------------------------------------------------------------------- /commonlib/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %-4relative [%thread] %-5level %logger{35} - %msg %n 8 | 9 | 10 | 11 | 12 | commonlib.log 13 | false 14 | 16 | 17 | %-4r %-5level %logger{35}: %msg%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /startWebDriverGridHub.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | SETLOCAL ENABLEDELAYEDEXPANSION 3 | SET TITLETEXT=WebDriver Grid Hub on 4444 4 | TITLE %TITLETEXT% 5 | 6 | ECHO ********************************************* 7 | ECHO * 8 | ECHO * WebDriver grid Hub instance. 9 | ECHO * 10 | ECHO * http://localhost:4444/grid/console 11 | ECHO * 12 | ECHO ********************************************* 13 | ECHO. 14 | 15 | SET JAR=selenium-server-standalone-2.35.0.jar 16 | SET "WGET=C:\Program Files (x86)\GnuWin32\bin\wget.exe" 17 | 18 | IF NOT DEFINED JAVA_HOME ( 19 | ECHO You must define a JAVA_HOME environment variable before you run this script. 20 | GOTO :ERROR 21 | ) 22 | SET "PATH=%JAVA_HOME%\bin;%PATH%" 23 | 24 | IF NOT EXIST %JAR% ( 25 | ECHO Selenium standalone server .jar is missing. 26 | IF EXIST "%WGET%" ( 27 | "%WGET%" --dot-style=binary http://selenium.googlecode.com/files/%JAR% 28 | TITLE %TITLETEXT% 29 | ) ELSE ( 30 | ECHO Wget.exe is missing. Install GNU Utils. 31 | ECHO. 32 | GOTO :ERROR 33 | ) 34 | ) 35 | ECHO. 36 | 37 | java.exe -jar %JAR% -role hub -hubConfig hubConfig.json -debug 38 | IF NOT %ERRORLEVEL%==0 GOTO :ERROR 39 | 40 | GOTO :END 41 | :ERROR 42 | ECHO There may have been an error. Try running the script again. 43 | pause 44 | :END 45 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | WebDriverTestingTemplate 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.springsource.ide.eclipse.gradle.core.nature 16 | org.eclipse.jdt.core.javanature 17 | 18 | 19 | 20 | 1376843160438 21 | 22 | 26 23 | 24 | org.eclipse.ui.ide.orFilterMatcher 25 | 26 | 27 | org.eclipse.ui.ide.multiFilter 28 | 1.0-projectRelativePath-equals-true-false-google 29 | 30 | 31 | org.eclipse.ui.ide.multiFilter 32 | 1.0-projectRelativePath-equals-true-false-commonlib 33 | 34 | 35 | org.eclipse.ui.ide.multiFilter 36 | 1.0-projectRelativePath-equals-true-false-parallelwebdriver 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /commonlib/src/main/java/qa/webdriver/util/CoreUtils.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.util; 2 | 3 | import java.io.File; 4 | import java.text.DecimalFormat; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public abstract class CoreUtils { 9 | 10 | public static Logger LOGGER = LoggerFactory.getLogger( "StaticLogger" ); 11 | protected Logger classlogger = LoggerFactory.getLogger( getClass() ); 12 | public static String separator = System.getProperty("file.separator"); 13 | 14 | /** 15 | * This can load a gradle resource, such as a .properties file. 16 | * 17 | * @param fileName 18 | * @return 19 | */ 20 | public static File loadGradleResource( String fileName ) { 21 | File junitFile = new File( fileName ); 22 | if ( junitFile.exists() ) { 23 | LOGGER.info( "The file '" + junitFile.getAbsolutePath() + "' exists." ); 24 | } else { 25 | LOGGER.info( "Problem loading Gradle resource: " + junitFile.getAbsolutePath() ); 26 | } 27 | return junitFile; 28 | } 29 | 30 | public static void waitTimer( int units, int mills ) { 31 | DecimalFormat df = new DecimalFormat("###.##"); 32 | double totalSeconds = ((double)units*mills)/1000; 33 | LOGGER.info("Explicit pause for " + df.format(totalSeconds) + " seconds divided by " + units + " units of time: "); 34 | try { 35 | Thread.currentThread(); 36 | int x = 0; 37 | while( x < units ) { 38 | Thread.sleep( mills ); 39 | LOGGER.info("."); 40 | x = x + 1; 41 | } 42 | } catch ( InterruptedException ex ) { 43 | ex.printStackTrace(); 44 | } 45 | } 46 | 47 | protected CoreUtils() { 48 | // do nothing 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /startWebDriverGridNode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "WebDriver Grid Hub on 4444" 4 | echo "" 5 | 6 | echo "*********************************************" 7 | echo "*" 8 | echo "* WebDriver Grid Node" 9 | echo "* It requires that a WebDriver JSON Hub is already running, usually on port 5555." 10 | echo "* You can run more than one of these if each has its own JSON config file." 11 | echo "*" 12 | echo "*********************************************" 13 | echo "" 14 | 15 | chromedriverzip=chromedriver_linux64_2.2.zip 16 | chromedriverbin=chromedriver 17 | jarfile="selenium-server-standalone-2.35.0.jar" 18 | wgetbin="/usr/bin/wget" 19 | 20 | if [ -z "${JAVA_HOME+xxx}" ]; then 21 | echo JAVA_HOME is not set at all; 22 | exit 1 23 | fi 24 | 25 | echo JARFILE=$jarfile 26 | echo WGET=$wgetbin 27 | echo JAVA_HOME=$JAVA_HOME 28 | export PATH="$JAVA_HOME/bin:$PATH" 29 | echo PATH=$PATH 30 | 31 | if [ ! -f $jarfile ]; then 32 | echo "Jar file not found!" 33 | if [ -f $wgetbin ]; then 34 | echo "Wget binary is found!" 35 | echo "Downloading Selenium standalone .jar file..." 36 | echo "" 37 | $wgetbin --dot-style=binary http://selenium.googlecode.com/files/$jarfile 38 | else 39 | echo "Wget.exe is missing." 40 | echo "" 41 | exit 1 42 | fi 43 | fi 44 | 45 | if [ ! -f $chromedriverbin ]; then 46 | if [ ! -f $chromedriverzip ]; then 47 | echo "Downloading Selenium chromedriver file..." 48 | echo "" 49 | $wgetbin --dot-style=binary --no-check-certificate https://chromedriver.googlecode.com/files/$chromedriverzip 50 | else 51 | echo "Chrome driver was found in current directory." 52 | echo "" 53 | fi 54 | $JAVA_HOME/bin/jar xvf $chromedriverzip 55 | rm -rf $chromedriverzip 56 | fi 57 | 58 | $JAVA_HOME/bin/java -jar $jarfile -role node -nodeConfig node1ConfigLinux.json -Dwebdriver.chrome.driver=$chromedriverbin 59 | -------------------------------------------------------------------------------- /google/src/test/java/qa/webdriver/tests/DataProviderTest.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.tests; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import org.junit.After; 10 | import org.junit.Before; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.junit.runners.Parameterized; 14 | import org.junit.runners.Parameterized.Parameters; 15 | import au.com.bytecode.opencsv.CSVReader; 16 | 17 | import qa.webdriver.util.WebDriverUtils; 18 | 19 | @RunWith(Parameterized.class) 20 | public class DataProviderTest extends WebDriverUtils { 21 | 22 | private static String testName, searchString, ddMatch; 23 | 24 | public DataProviderTest( String tName, String sString, String dMatch ) { 25 | testName = tName; 26 | searchString = sString; 27 | ddMatch = dMatch; 28 | testXOffset = 700; 29 | } 30 | 31 | @Before 32 | public void setUp() { 33 | LOGGER.info("setUp"); 34 | } 35 | 36 | @Parameters(name = "{0}: {1}: {2}") 37 | public static List loadParams() { 38 | File tFile = loadGradleResource( System.getProperty("user.dir") + separator + "build" + 39 | separator + "resources" + separator + "test" + separator + "testdata2.csv" ); 40 | List rows = null; 41 | if ( tFile.exists() ) { 42 | CSVReader reader = null; 43 | try { 44 | reader = new CSVReader( new FileReader( tFile ), ',' ); 45 | rows = reader.readAll(); 46 | } catch (FileNotFoundException e) { 47 | e.printStackTrace(); 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | //String[][] csvMatrix = rows.toArray(new String[rows.size()][]); 53 | LOGGER.info("Finished loadParams()"); 54 | return rows; 55 | } 56 | 57 | @Test 58 | public void testParams() { 59 | LOGGER.info("Param '{}' being run...", testName ); 60 | LOGGER.info("Search string: " + searchString ); 61 | LOGGER.info("ddMatch: " + ddMatch ); 62 | LOGGER.info("Test '{}' is done.", testName ); 63 | } 64 | 65 | @After 66 | public void cleanUp() { 67 | LOGGER.info("Finished cleanUp"); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /parallelwebdriver/src/main/java/webdriver/test/MainPage.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import static org.junit.Assert.*; 4 | import org.openqa.selenium.Keys; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.remote.RemoteWebDriver; 7 | import org.openqa.selenium.support.CacheLookup; 8 | import org.openqa.selenium.support.FindBy; 9 | import org.openqa.selenium.support.PageFactory; 10 | import org.openqa.selenium.support.ui.LoadableComponent; 11 | import static qa.webdriver.util.WebDriverUtils.*; 12 | 13 | public class MainPage extends LoadableComponent { 14 | 15 | private RemoteWebDriver driver; 16 | 17 | @FindBy(id = "textFieldTestInputControlID" ) 18 | @CacheLookup 19 | public WebElement inputControlTextField; 20 | 21 | @FindBy(id = "textFieldTestProcessButtonID" ) 22 | @CacheLookup 23 | public WebElement controlButton; 24 | 25 | public MainPage( RemoteWebDriver drv ) { 26 | super(); 27 | this.driver = drv; 28 | driver.switchTo().defaultContent(); 29 | LOGGER.info("MainPage constructor..."); 30 | } 31 | 32 | public void setControlInputField( String text ) { 33 | clearAndType( inputControlTextField, text ); 34 | } 35 | 36 | public void clearAndSetValue( WebElement field, String text ) { 37 | field.clear(); 38 | field.sendKeys( Keys.chord(Keys.CONTROL, "a" ), text ); 39 | } 40 | 41 | public void clearAndType( WebElement field, String text ) { 42 | field.clear(); 43 | field.sendKeys( text ); 44 | } 45 | 46 | @Override 47 | protected void isLoaded() { 48 | LOGGER.info("MainPage.isLoaded()..."); 49 | PageFactory.initElements( driver, this ); 50 | assertTrue( "Title is not yet available.", driver.getTitle().equals("w1.html") ); 51 | } 52 | 53 | /** 54 | * Method: load 55 | * Overidden method from the LoadableComponent class. 56 | * @return void 57 | * @throws null 58 | */ 59 | @Override 60 | protected void load() { 61 | LOGGER.info("MainPage.load()..."); 62 | waitTimer(1, 1000); 63 | } 64 | 65 | /** 66 | * Because of how the page object is initialized, we are using getAttribute here 67 | * @param sstr 68 | * @return void 69 | */ 70 | public void clickControlButton() { 71 | controlButton.click(); 72 | } 73 | 74 | 75 | } 76 | -------------------------------------------------------------------------------- /startWebDriverGridNode.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | SETLOCAL ENABLEDELAYEDEXPANSION 3 | SET TITLETEXT=WebDriver Grid Node 4 | TITLE %TITLETEXT% 5 | 6 | :: Proxy for Fiddler or for BrowserMob 7 | SET PROXY=false 8 | 9 | SET CHROMEDRIVERZIP=chromedriver_win32_2.2.zip 10 | SET CHROMEDRIVER=chromedriver.exe 11 | SET JAR=selenium-server-standalone-2.35.0.jar 12 | SET IEDRIVERZIP=IEDriverServer_Win32_2.35.1.zip 13 | SET IEDRIVER=IEDriverServer.exe 14 | SET "WGET=C:\Program Files (x86)\GnuWin32\bin\wget.exe" 15 | 16 | ECHO ********************************************* 17 | ECHO * 18 | ECHO * WebDriver Grid Node 19 | ECHO * It requires that a WebDriver JSON Hub is already running, usually on port 5555. 20 | ECHO * You can run more than one of these if each has its own JSON config file. 21 | ECHO * 22 | ECHO ********************************************* 23 | ECHO. 24 | 25 | IF NOT DEFINED JAVA_HOME ( 26 | ECHO You must define a JAVA_HOME environment variable before you run this script. 27 | GOTO :ERROR 28 | ) 29 | SET "PATH=.;%JAVA_HOME%\bin;%PATH%" 30 | 31 | IF NOT EXIST %JAR% ( 32 | IF EXIST "%WGET%" ( 33 | "%WGET%" --dot-style=binary http://selenium.googlecode.com/files/%JAR% 34 | ) ELSE ( 35 | ECHO Wget.exe is missing. Install GNU utils. & GOTO :ERROR 36 | ) 37 | ) 38 | 39 | IF NOT EXIST %IEDRIVER% ( 40 | IF EXIST "%WGET%" ( 41 | "%WGET%" --dot-style=binary http://selenium.googlecode.com/files/%IEDRIVERZIP% 42 | jar.exe xvf %IEDRIVERZIP% 43 | DEL /Q %IEDRIVERZIP% 44 | ) ELSE ( 45 | ECHO Wget.exe is missing. & GOTO :ERROR 46 | ) 47 | ) 48 | 49 | IF NOT EXIST %CHROMEDRIVER% ( 50 | IF EXIST "%WGET%" ( 51 | "%WGET%" --dot-style=binary --no-check-certificate https://chromedriver.googlecode.com/files/%CHROMEDRIVERZIP% 52 | jar.exe xvf %CHROMEDRIVERZIP% 53 | DEL /Q %CHROMEDRIVERZIP% 54 | ) ELSE ( 55 | ECHO Wget.exe is missing. & GOTO :ERROR 56 | ) 57 | ) 58 | 59 | ECHO. 60 | ECHO ====================== 61 | ECHO Grid Hub status : & netstat -an | FIND "4444" 62 | IF NOT %ERRORLEVEL%==0 ( 63 | ECHO Hub is required to run first. 64 | :: You can disable this check if you need to run a Node on a different computer. 65 | ECHO. 66 | GOTO :ERROR 67 | ) 68 | ECHO ====================== 69 | ECHO. 70 | 71 | :: Set JAVA_OPTS java options to JVM 72 | SET "JAVA_OPTS=-Dwebdriver.chrome.driver=%CHROMEDRIVER%" 73 | IF "%PROXY%"=="true" SET "JAVA_OPTS=%JAVA_OPTS% -DproxySet=true -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888" 74 | 75 | TITLE %TITLETEXT% 76 | java.exe -jar %JAR% -role node -nodeConfig node1Config.json %JAVA_OPTS% 77 | 78 | GOTO :END 79 | :ERROR 80 | pause 81 | :END -------------------------------------------------------------------------------- /parallelwebdriver/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | //apply plugin: 'idea' 3 | apply plugin: 'eclipse' 4 | group = 'selenium.webdriver.qa' 5 | 6 | ext { 7 | projTitle = 'Test Parallel MultiWindow' 8 | projVersion = '1.0' 9 | } 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | compile project(':commonlib') 17 | compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+' 18 | compile group: 'commons-collections', name: 'commons-collections', version: '3.+' 19 | compile group: 'junit', name: 'junit', version: '4.+' 20 | compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.+' 21 | compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.+' 22 | } 23 | 24 | tasks.withType(Test) { 25 | 26 | jvmArgs '-Xms128m', '-Xmx1024m', '-XX:MaxPermSize=128m' 27 | maxParallelForks = 4 28 | testLogging.showStandardStreams = true 29 | systemProperties['testProtocol'] = 'http' 30 | systemProperties['testDomain'] = 'djangofan.github.io' 31 | systemProperties['testPort'] = 80 32 | systemProperties['testUri'] = '/html-test-site/site' 33 | systemProperties['hubUrl'] = 'localhost' 34 | systemProperties['hubPort'] = '4444' 35 | 36 | } 37 | 38 | task runParallelTestsInFirefox(type: Test) { 39 | description = 'Runs all JUnit test classes in parallel threads.' 40 | //include '**/TestFrames.class' 41 | include '**/TestHandleCache*.class' 42 | reports.junitXml.destination = "$buildDir/test-results/ParallelTestsFF" 43 | reports.html.destination = "$buildDir/test-results/ParallelTestsFF" 44 | 45 | // System properties passed to tests 46 | systemProperties['browserType'] = 'firefox' 47 | 48 | // initial browser size and position 49 | systemProperties['windowXPosition'] = '100' 50 | systemProperties['windowYPosition'] = '40' 51 | systemProperties['windowWidth'] = '400' 52 | systemProperties['windowHeight'] = '600' 53 | } 54 | 55 | task runFrameTestInIE(type: Test) { 56 | description = 'Runs a test of handling iframes.' 57 | maxParallelForks = 2 58 | //include '**/TestFrames.class' 59 | include '**/TestHandleCache*.class' 60 | reports.junitXml.destination = "$buildDir/test-results/ParallelTestsIE" 61 | reports.html.destination = "$buildDir/test-results/ParallelTestsIE" 62 | 63 | // System properties passed to tests 64 | systemProperties['browserType'] = 'ie' 65 | 66 | // initial browser size and position 67 | systemProperties['windowXPosition'] = '100' 68 | systemProperties['windowYPosition'] = '40' 69 | systemProperties['windowWidth'] = '900' 70 | systemProperties['windowHeight'] = '600' 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /google/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | //apply plugin: 'idea' 3 | apply plugin: 'eclipse' 4 | group = 'selenium.webdriver.qa' 5 | 6 | ext { 7 | projTitle = 'WebDriver on Google' 8 | projVersion = '1.0' 9 | buildDirectory = '$buildDir' 10 | } 11 | 12 | repositories { 13 | mavenCentral() 14 | // javacpp and javacv are required by Sikuli 15 | maven { 16 | url "http://maven2.javacpp.googlecode.com/git/" 17 | } 18 | maven { 19 | url "http://maven2.javacv.googlecode.com/git/" 20 | } 21 | } 22 | 23 | dependencies { 24 | compile project(':commonlib') 25 | compile group: 'org.sikuli', name: 'sikuli-api', version: '1.0.+' 26 | compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.+' 27 | compile group: 'commons-io', name: 'commons-io', version: '1.3.+' 28 | compile group: 'junit', name: 'junit', version: '4.+' 29 | compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.+' 30 | compile group: 'net.sf.opencsv', name: 'opencsv', version: '2.+' 31 | } 32 | 33 | // run tests with -info or -debug option to get logging 34 | tasks.withType(Test) { 35 | 36 | jvmArgs '-Xms128m', '-Xmx1024m', '-XX:MaxPermSize=128m' 37 | 38 | testLogging { 39 | exceptionFormat "full" 40 | events "started", "passed", "skipped", "failed", "standardOut", "standardError" 41 | displayGranularity = 0 42 | showStandardStreams = false 43 | } 44 | beforeTest { descriptor -> 45 | logger.lifecycle("Running test: " + descriptor) 46 | } 47 | 48 | systemProperties['hubIP'] = '127.0.0.1' 49 | systemProperties['hubPort'] = '4444' 50 | systemProperties['testURL'] = 'http://www.google.com/' 51 | 52 | // initial browser size and position 53 | systemProperties['windowXPosition'] = '40' 54 | systemProperties['windowYPosition'] = '40' 55 | systemProperties['windowWidth'] = '900' 56 | systemProperties['windowHeight'] = '600' 57 | 58 | } 59 | 60 | task runAllTestsInFirefox(type: Test) { 61 | maxParallelForks = 2 62 | systemProperties['browser'] = 'firefox' 63 | include '**/GoogleTest*.class' 64 | reports.junitXml.destination = "$buildDir/test-results/GoogleTestFF" 65 | reports.html.destination = "$buildDir/test-results/GoogleTestFF" 66 | } 67 | 68 | task runAllTestsInIE(type: Test) { 69 | maxParallelForks = 1 70 | systemProperties['browser'] = 'ie' 71 | include '**/GoogleTest*.class' 72 | reports.junitXml.destination = "$buildDir/test-results/GoogleTestIE" 73 | reports.html.destination = "$buildDir/test-results/GoogleTestIE" 74 | } 75 | 76 | task runAllTestsInChrome(type: Test) { 77 | maxParallelForks = 2 78 | systemProperties['browser'] = 'chrome' 79 | systemProperties['webdriver.chrome.driver'] = 'chromedriver.exe' 80 | include '**/GoogleTest*.class' 81 | reports.junitXml.destination = "$buildDir/test-results/GoogleTestCH" 82 | reports.html.destination = "$buildDir/test-results/GoogleTestCH" 83 | } 84 | 85 | task runParameterizedExample(type: Test) { 86 | include '**/DataProviderTest.class' 87 | // test output goes to default location 88 | } 89 | 90 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | ip.txt 19 | 20 | # External tool builders 21 | .externalToolBuilders/ 22 | 23 | # Locally stored "Eclipse launch configurations" 24 | *.launch 25 | 26 | # CDT-specific 27 | .cproject 28 | 29 | # PDT-specific 30 | .buildpath 31 | 32 | 33 | ################# 34 | ## Visual Studio 35 | ################# 36 | 37 | ## Ignore Visual Studio temporary files, build results, and 38 | ## files generated by popular Visual Studio add-ons. 39 | 40 | # User-specific files 41 | *.suo 42 | *.user 43 | *.sln.docstates 44 | 45 | # Build results 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | *_i.c 49 | *_p.c 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.vspscc 64 | .builds 65 | *.dotCover 66 | 67 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 68 | #packages/ 69 | 70 | # Visual C++ cache files 71 | ipch/ 72 | *.aps 73 | *.ncb 74 | *.opensdf 75 | *.sdf 76 | 77 | # Visual Studio profiler 78 | *.psess 79 | *.vsp 80 | 81 | # ReSharper is a .NET coding add-in 82 | _ReSharper* 83 | 84 | # Installshield output folder 85 | [Ee]xpress 86 | 87 | # DocProject is a documentation generator add-in 88 | DocProject/buildhelp/ 89 | DocProject/Help/*.HxT 90 | DocProject/Help/*.HxC 91 | DocProject/Help/*.hhc 92 | DocProject/Help/*.hhk 93 | DocProject/Help/*.hhp 94 | DocProject/Help/Html2 95 | DocProject/Help/html 96 | 97 | # Click-Once directory 98 | publish 99 | 100 | # Others 101 | [Bb]in 102 | [Oo]bj 103 | sql 104 | TestResults 105 | *.Cache 106 | ClientBin 107 | stylecop.* 108 | ~$* 109 | *.dbmdl 110 | Generated_Code #added for RIA/Silverlight projects 111 | 112 | # Backup & report files from converting an old project file to a newer 113 | # Visual Studio version. Backup files are not needed, because we have git ;-) 114 | _UpgradeReport_Files/ 115 | Backup*/ 116 | UpgradeLog*.XML 117 | 118 | 119 | 120 | ############ 121 | ## Windows 122 | ############ 123 | 124 | # Windows image file caches 125 | Thumbs.db 126 | 127 | # Folder config file 128 | Desktop.ini 129 | 130 | 131 | ############# 132 | ## Python 133 | ############# 134 | 135 | *.py[co] 136 | 137 | # Packages 138 | *.egg 139 | *.egg-info 140 | dist 141 | build 142 | eggs 143 | parts 144 | bin 145 | var 146 | sdist 147 | develop-eggs 148 | .installed.cfg 149 | 150 | # Installer logs 151 | pip-log.txt 152 | 153 | # Unit test / coverage reports 154 | .coverage 155 | .tox 156 | 157 | #Translations 158 | *.mo 159 | 160 | #Mr Developer 161 | .mr.developer.cfg 162 | 163 | # Mac crap 164 | .DS_Store 165 | 166 | # GitHub files 167 | *.bin 168 | cache.* 169 | .gradle 170 | *.jar 171 | *.exe 172 | 173 | # To support IntelliJ IDEA , will disable these later when I get IntelliJ working correctly 174 | .idea 175 | *.iml 176 | *.ipr 177 | *.iws 178 | 179 | # Don't add logback log4j files to source 180 | *.log 181 | 182 | -------------------------------------------------------------------------------- /google/src/test/java/qa/webdriver/tests/GoogleTest1.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.tests; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import org.junit.Before; 10 | import org.junit.After; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.junit.runners.Parameterized; 14 | import org.junit.runners.Parameterized.Parameters; 15 | import org.openqa.selenium.By; 16 | 17 | import au.com.bytecode.opencsv.CSVReader; 18 | 19 | import qa.webdriver.util.GoogleSearchPage; 20 | import qa.webdriver.util.WebDriverUtils; 21 | 22 | @RunWith(Parameterized.class) 23 | public class GoogleTest1 extends WebDriverUtils { 24 | 25 | private static String testName, searchString, ddMatch; 26 | 27 | public GoogleTest1( String tName, String sString, String dMatch ) { 28 | testName = tName; 29 | searchString = sString; 30 | ddMatch = dMatch; 31 | testXOffset = 0; 32 | } 33 | 34 | @Before 35 | public void setUp() { 36 | if ( driver == null ) initializeRemoteBrowser( System.getProperty("browser"), 37 | System.getProperty("hubIP"), Integer.parseInt( System.getProperty("hubPort") ) ); 38 | classlogger.info("Finished setUpGoogleTest1"); 39 | } 40 | 41 | @Parameters(name = "{0}: {1}: {2}") 42 | public static Iterable loadTestsFromFile1() { 43 | File tFile = loadGradleResource( System.getProperty("user.dir") + separator + "build" + 44 | separator + "resources" + separator + "test" + separator + "testdata1.csv" ); 45 | List rows = null; 46 | if ( tFile.exists() ) { 47 | CSVReader reader = null; 48 | try { 49 | reader = new CSVReader( new FileReader( tFile ), ',' ); 50 | rows = reader.readAll(); 51 | } catch (FileNotFoundException e) { 52 | e.printStackTrace(); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | LOGGER.info("Finished loadTestsFromFile1()"); 58 | return rows; 59 | } 60 | 61 | @Test 62 | public void testWithPageObject() { 63 | classlogger.info("{} being run...", testName ); 64 | driver.get( System.getProperty("testURL") ); 65 | GoogleSearchPage gs = new GoogleSearchPage(); 66 | gs.setSearchString( searchString ); 67 | gs.selectInGoogleDropdown( ddMatch ); 68 | gs.clickSearchButton(); 69 | waitTimer(2, 1000); 70 | getElementByLocator( By.cssSelector( "div.gbqlca" ) ).click(); // click Google logo 71 | classlogger.info("Page object test '{}' is done.", testName ); 72 | } 73 | 74 | @Test 75 | public void testFluentPageObject() { 76 | classlogger.info("{} being run...", testName ); 77 | driver.get( System.getProperty("testURL") + "webhp?hl=en&tab=ww" ); 78 | GoogleSearchPage gsp = new GoogleSearchPage(); 79 | gsp.withFluent().clickSearchField() 80 | .setSearchString( searchString ).waitForTime(2, 1000) 81 | .selectItem( ddMatch ).clickSearchButton() 82 | .waitForTime(2, 1000).clickLogo(); //click Google logo 83 | classlogger.info("Fluent test '{}' is done.", testName ); 84 | } 85 | 86 | @After 87 | public void cleanUp() { 88 | classlogger.info("Finished cleanUpGoogleTest1"); 89 | driver.get("about:about"); 90 | // remaining open browser window will garbage collect within 30 seconds 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /google/src/test/java/qa/webdriver/tests/GoogleTest2.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.tests; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.FileReader; 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | import org.junit.Before; 10 | import org.junit.After; 11 | import org.junit.Test; 12 | import org.junit.runner.RunWith; 13 | import org.junit.runners.Parameterized; 14 | import org.junit.runners.Parameterized.Parameters; 15 | import org.openqa.selenium.By; 16 | 17 | import au.com.bytecode.opencsv.CSVReader; 18 | 19 | import qa.webdriver.util.GoogleSearchPage; 20 | import qa.webdriver.util.WebDriverUtils; 21 | 22 | @RunWith(Parameterized.class) 23 | public class GoogleTest2 extends WebDriverUtils { 24 | 25 | private static String testName, searchString, ddMatch; 26 | 27 | public GoogleTest2( String tName, String sString, String dMatch ) { 28 | testName = tName; 29 | searchString = sString; 30 | ddMatch = dMatch; 31 | testXOffset = 700; 32 | } 33 | 34 | @Before 35 | public void setUp() { 36 | if ( driver == null ) initializeRemoteBrowser( System.getProperty("browser"), 37 | System.getProperty("hubIP"), Integer.parseInt( System.getProperty("hubPort") ) ); 38 | classlogger.info("Finished setUpGoogleTest2"); 39 | } 40 | 41 | @Parameters(name = "{0}: {1}: {2}") 42 | public static Iterable loadTestsFromFile2() { 43 | File tFile = loadGradleResource( System.getProperty("user.dir") + separator + "build" + 44 | separator + "resources" + separator + "test" + separator + "testdata2.csv" ); 45 | List rows = null; 46 | if ( tFile.exists() ) { 47 | CSVReader reader = null; 48 | try { 49 | reader = new CSVReader( new FileReader( tFile ), ',' ); 50 | rows = reader.readAll(); 51 | } catch (FileNotFoundException e) { 52 | e.printStackTrace(); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | LOGGER.info("Finished loadTestsFromFile2()"); 58 | return rows; 59 | } 60 | 61 | @Test 62 | public void testWithPageObject() { 63 | classlogger.info("{} being run...", testName ); 64 | driver.get( System.getProperty("testURL") ); 65 | GoogleSearchPage gs = new GoogleSearchPage(); 66 | gs.setSearchString( searchString ); 67 | gs.selectInGoogleDropdown( ddMatch ); 68 | gs.clickSearchButton(); 69 | waitTimer(2, 1000); 70 | getElementByLocator( By.cssSelector( "div.gbqlca" ) ).click(); // click Google logo 71 | classlogger.info("Page object test '{}' is done.", testName ); 72 | } 73 | 74 | @Test 75 | public void testFluentPageObject() { 76 | classlogger.info("{} being run...", testName ); 77 | driver.get( System.getProperty("testURL") + "webhp?hl=en&tab=ww" ); 78 | GoogleSearchPage gsp = new GoogleSearchPage(); 79 | gsp.withFluent().clickSearchField() 80 | .setSearchString( searchString ).waitForTime(2, 1000) 81 | .selectItem( ddMatch ).clickSearchButton() 82 | .waitForTime(2, 1000).clickLogo(); //click Google logo 83 | classlogger.info("Fluent test '{}' is done.", testName ); 84 | } 85 | 86 | @After 87 | public void cleanUp() { 88 | classlogger.info("Finished cleanUpGoogleTest2"); 89 | driver.get("about:about"); 90 | // remaining open browser window will garbage collect within 30 seconds 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /parallelwebdriver/src/main/java/webdriver/test/IFrame2.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.Keys; 9 | import org.openqa.selenium.NoSuchElementException; 10 | import org.openqa.selenium.WebDriver; 11 | import org.openqa.selenium.WebElement; 12 | import org.openqa.selenium.remote.RemoteWebDriver; 13 | import org.openqa.selenium.support.FindBy; 14 | import org.openqa.selenium.support.PageFactory; 15 | import org.openqa.selenium.support.ui.ExpectedConditions; 16 | import org.openqa.selenium.support.ui.FluentWait; 17 | import org.openqa.selenium.support.ui.LoadableComponent; 18 | import org.openqa.selenium.support.ui.Wait; 19 | 20 | import static qa.webdriver.util.WebDriverUtils.*; 21 | 22 | public class IFrame2 extends LoadableComponent { 23 | 24 | private RemoteWebDriver driver; 25 | 26 | @FindBy(id = "iFrame2TextFieldTestInputControlID" ) public WebElement iFrame2TextFieldInput; 27 | @FindBy(id = "iFrame2TextFieldTestProcessButtonID" ) public WebElement copyButton; 28 | 29 | public IFrame2( RemoteWebDriver drv ) { 30 | super(); 31 | this.driver = drv; 32 | this.driver.switchTo().defaultContent(); 33 | waitTimer(1, 1000); 34 | this.driver.switchTo().frame("BodyFrame2"); 35 | LOGGER.info("IFrame1 constructor..."); 36 | } 37 | 38 | public void setInputField( String text ) { 39 | clearAndType( iFrame2TextFieldInput, text ); 40 | } 41 | 42 | public void clearAndSetValue( WebElement field, String text ) { 43 | field.clear(); 44 | field.sendKeys( Keys.chord(Keys.CONTROL, "a" ), text ); 45 | } 46 | 47 | public void clearAndType( WebElement field, String text ) { 48 | field.clear(); 49 | field.sendKeys( text ); 50 | } 51 | 52 | @Override 53 | protected void isLoaded() throws Error { 54 | LOGGER.info("IFrame2.isLoaded()..."); 55 | PageFactory.initElements( driver, this ); 56 | try { 57 | assertTrue( "Page visible title is not yet available.", 58 | driver.findElementByCssSelector("body form#webDriverUnitiFrame2TestFormID h1") 59 | .getText().equals("iFrame2 Test") ); 60 | } catch ( NoSuchElementException e) { 61 | LOGGER.info("No such element." ); 62 | assertTrue("No such element.", false); 63 | } 64 | } 65 | 66 | /** 67 | * Method: load 68 | * Overidden method from the LoadableComponent class. 69 | * @return void 70 | * @throws null 71 | */ 72 | @Override 73 | protected void load() { 74 | LOGGER.info("IFrame2.load()..."); 75 | Wait wait = new FluentWait( driver ) 76 | .withTimeout(30, TimeUnit.SECONDS) 77 | .pollingEvery(5, TimeUnit.SECONDS) 78 | .ignoring( NoSuchElementException.class ) ; 79 | //.ignoring( StaleElementReferenceException.class ) ; 80 | wait.until( ExpectedConditions.presenceOfElementLocated( 81 | By.cssSelector("body form#webDriverUnitiFrame2TestFormID h1") ) ); 82 | } 83 | 84 | /** 85 | * Because of how the page object is initialized, we are using getAttribute here 86 | * @param sstr 87 | * @return void 88 | */ 89 | public void clickCopyButton() { 90 | copyButton.click(); 91 | } 92 | 93 | public void exitFrame() { 94 | this.driver.switchTo().defaultContent(); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /parallelwebdriver/src/main/java/webdriver/test/IFrame1.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.openqa.selenium.By; 8 | import org.openqa.selenium.Keys; 9 | import org.openqa.selenium.NoSuchElementException; 10 | import org.openqa.selenium.WebDriver; 11 | import org.openqa.selenium.WebElement; 12 | import org.openqa.selenium.remote.RemoteWebDriver; 13 | import org.openqa.selenium.support.FindBy; 14 | import org.openqa.selenium.support.PageFactory; 15 | import org.openqa.selenium.support.ui.ExpectedConditions; 16 | import org.openqa.selenium.support.ui.FluentWait; 17 | import org.openqa.selenium.support.ui.LoadableComponent; 18 | import org.openqa.selenium.support.ui.Wait; 19 | 20 | import static qa.webdriver.util.CoreUtils.LOGGER; 21 | import static qa.webdriver.util.CoreUtils.waitTimer; 22 | 23 | public class IFrame1 extends LoadableComponent { 24 | 25 | private RemoteWebDriver driver; 26 | 27 | @FindBy(id = "iFrame1TextFieldTestInputControlID" ) public WebElement iFrame1TextFieldInput; 28 | @FindBy(id = "iFrame1TextFieldTestProcessButtonID" ) public WebElement copyButton; 29 | 30 | public IFrame1( RemoteWebDriver drv ) { 31 | super(); 32 | this.driver = drv; 33 | this.driver.switchTo().defaultContent(); 34 | waitTimer(1, 1000); 35 | this.driver.switchTo().frame("BodyFrame1"); 36 | LOGGER.info("IFrame1 constructor..."); 37 | } 38 | 39 | public void setInputField( String text ) { 40 | clearAndType( iFrame1TextFieldInput, text ); 41 | } 42 | 43 | public void clearAndSetValue( WebElement field, String text ) { 44 | field.clear(); 45 | field.sendKeys( Keys.chord(Keys.CONTROL, "a" ), text ); 46 | } 47 | 48 | public void clearAndType( WebElement field, String text ) { 49 | field.clear(); 50 | field.sendKeys( text ); 51 | } 52 | 53 | @Override 54 | protected void isLoaded() throws Error { 55 | LOGGER.info("IFrame1.isLoaded()..."); 56 | PageFactory.initElements( driver, this ); 57 | try { 58 | assertTrue( "Page visible title is not yet available.", 59 | driver.findElementByCssSelector("body form#webDriverUnitiFrame1TestFormID h1") 60 | .getText().equals("iFrame1 Test") ); 61 | } catch ( NoSuchElementException e) { 62 | LOGGER.info("No such element." ); 63 | assertTrue("No such element.", false); 64 | } 65 | } 66 | 67 | /** 68 | * Method: load 69 | * Overidden method from the LoadableComponent class. 70 | * @return void 71 | * @throws null 72 | */ 73 | @Override 74 | protected void load() { 75 | LOGGER.info("IFrame1.load()..."); 76 | Wait wait = new FluentWait( driver ) 77 | .withTimeout(30, TimeUnit.SECONDS) 78 | .pollingEvery(5, TimeUnit.SECONDS) 79 | .ignoring( NoSuchElementException.class ) ; 80 | //.ignoring( StaleElementReferenceException.class ) ; 81 | wait.until( ExpectedConditions.presenceOfElementLocated( 82 | By.cssSelector("body form#webDriverUnitiFrame1TestFormID h1") ) ); 83 | } 84 | 85 | /** 86 | * Because of how the page object is initialized, we are using getAttribute here 87 | * @param sstr 88 | * @return void 89 | */ 90 | public void clickCopyButton() { 91 | copyButton.click(); 92 | } 93 | 94 | public void exitFrame() { 95 | this.driver.switchTo().defaultContent(); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /parallelwebdriver/src/test/java/webdriver/test/TestFrames.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import org.junit.After; 4 | import org.junit.AfterClass; 5 | import org.junit.Before; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | import qa.webdriver.util.WebDriverUtils; 9 | 10 | /** 11 | * This class tests a multi-window handling method that I call "handle cache" 12 | * 13 | * @author Jon Thor Austen 14 | * 15 | */ 16 | public class TestFrames extends WebDriverUtils { 17 | 18 | /** 19 | * Load main window handle before tests 20 | */ 21 | public TestFrames() { 22 | classlogger.info("Called constructor for TestFrames..."); 23 | } 24 | 25 | /** 26 | * Setup web server before loading class 27 | */ 28 | @BeforeClass 29 | public static void setUpTestFramesClass() { 30 | LOGGER.info("Finished TestFramesClass"); 31 | } 32 | 33 | /** 34 | * Start main window handle for tests 35 | */ 36 | @Before 37 | public void setUpTestFrames() { 38 | testXOffset = 0; 39 | initializeRemoteBrowser( System.getProperty("browserType"), System.getProperty("hubUrl") , 40 | Integer.parseInt( System.getProperty("hubPort") ) ); 41 | System.out.println("TestFrames thread id = " + Thread.currentThread().getId()); 42 | classlogger.info("Finished setUpTestFrames"); 43 | } 44 | 45 | @Test 46 | public void testIFrame1() { 47 | classlogger.info("Starting test testIFrame1" ); 48 | driver.get( System.getProperty("testProtocol") + "://" + System.getProperty("testDomain") + ":" + 49 | System.getProperty("testPort") + System.getProperty("testUri") + "/w1.html#iFrame1" ); 50 | //MainPage mp1 = new MainPage( driver ).get(); 51 | IFrame1 if1 = new IFrame1( driver ).get(); 52 | waitTimer( 2, 1000); 53 | if1.setInputField("Iframe1 test." ); 54 | if1.clickCopyButton(); 55 | if1.exitFrame(); 56 | //mp1.setControlInputField( "Test input" ); 57 | //mp1.clickControlButton(); 58 | //mp1.clickControlButton(); 59 | waitTimer( 2, 1000); 60 | classlogger.info( "Finished testIFrame1" ); 61 | } 62 | 63 | @Test 64 | public void testIFrame2() { 65 | classlogger.info("Starting test testIFrame2" ); 66 | driver.get( System.getProperty("testProtocol") + "://" + System.getProperty("testDomain") + ":" + 67 | System.getProperty("testPort") + System.getProperty("testUri") + "/w1.html#iFrame2" ); 68 | //MainPage mp2 = new MainPage( driver ).get(); 69 | IFrame2 if2 = new IFrame2( driver ).get(); 70 | waitTimer( 2, 1000); 71 | if2.setInputField("Iframe2 test." ); 72 | if2.clickCopyButton(); 73 | if2.exitFrame(); 74 | //mp2.setControlInputField( "Test input" ); 75 | //mp2.clickControlButton(); 76 | //mp2.clickControlButton(); 77 | waitTimer( 2, 1000); 78 | classlogger.info( "Finished testIFrame2" ); 79 | } 80 | 81 | /** 82 | * Close main window handle after tests finish 83 | */ 84 | @After 85 | public void cleanUpTestFrames() { 86 | driver.switchTo().window( mainHandle ); 87 | showMessageInBrowser("Test finished."); 88 | updateHandleCache(); 89 | waitTimer(6, 500); 90 | closeAllBrowserWindows(); 91 | classlogger.info("Finished cleanUpTestFrames"); 92 | } 93 | 94 | /** 95 | * Cleanup any remaining objects after unloading class 96 | */ 97 | @AfterClass 98 | public static void tearDownTestFramesClass() { 99 | LOGGER.info("Finished tearDownTestFramesClass"); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /runProjectMenu.bat: -------------------------------------------------------------------------------- 1 | @ECHO off 2 | SET TITLETEXT=Gradle Run Script 3 | TITLE %TITLETEXT% 4 | 5 | :: Uncomment the next line to override JAVA_HOME on your system 6 | ::set JAVA_HOME=C:\Java\jdk1.6.0_33_x32 7 | 8 | IF NOT DEFINED JAVA_HOME ( 9 | ECHO JAVA_HOME must be defined as an environment variable. 10 | GOTO :END 11 | ) 12 | 13 | IF NOT DEFINED GRADLE_HOME ( 14 | ECHO GRADLE_HOME must be defined as an environment variable. 15 | ECHO Also, add GRADLE_HOME\bin to your path. 16 | ECHO. 17 | GOTO :END 18 | ) 19 | 20 | IF DEFINED GROOVY_HOME ( 21 | SET "PATH=%GROOVY_HOME%\bin;%PATH%" 22 | ) ELSE ( 23 | ECHO You might want to define GROOVY_HOME as an environment variable. 24 | ) 25 | 26 | SET "PATH=%JAVA_HOME%\bin;%GRADLE_HOME%\bin;%PATH%" 27 | 28 | CD root 29 | 30 | ::------------------------------------------------------------------- 31 | :: Parse first script argument for test action 32 | :: If no args are passed then prompt user for test to run 33 | ::------------------------------------------------------------------- 34 | 35 | :PICK 36 | ECHO Current directory is "%CD%" 37 | ECHO. 38 | SET CHOICE= 39 | ECHO.&ECHO.&ECHO. 40 | SET CHOICE=%~1 41 | IF "%~1"=="" ( 42 | ECHO. 43 | ECHO [1] Run ^"Google^" tests 44 | ECHO [2] Run ^"ParallelWebDriver^" tests 45 | ECHO [3] List all projects 46 | ECHO [4] Display ^"Google^" tasks 47 | ECHO [5] Display ^"ParallelWebDriver^" tasks 48 | ECHO [6] Display ^"CommonLib^" tasks 49 | ECHO [7] Run a custom task 50 | ECHO [8] Run Gradle GUI 51 | ECHO [X] EXIT 52 | ECHO. 53 | ) 54 | IF "%~1"=="" SET /P "CHOICE=Please enter a action you want to perform [1]: " 55 | IF "%CHOICE%"=="" ( 56 | SET CHOICE=1 57 | ) 58 | IF "%CHOICE%"=="X" ( 59 | GOTO :END 60 | ) 61 | IF "%CHOICE%"=="x" ( 62 | GOTO :END 63 | ) 64 | 65 | ::------------------------------------------------------------------- 66 | :: Run action 67 | ::------------------------------------------------------------------- 68 | 69 | IF "%CHOICE%"=="1" ( 70 | CALL gradle.bat commonlib:show commonLib:compileJava google:show google:clean google:runAllTestsInFirefox google:runAllTestsInIE -info 71 | GOTO :END 72 | ) ELSE IF "%CHOICE%"=="2" ( 73 | CALL gradle.bat commonlib:show commonLib:compileJava parallelwebdriver:show parallelwebdriver:clean parallelwebdriver:runParallelTests parallelwebdriver:runFrameTestInIE -info 74 | GOTO :PICK 75 | GOTO :END 76 | ) ELSE IF "%CHOICE%"=="3" ( 77 | CALL gradle.bat projects 78 | GOTO :PICK 79 | ) ELSE IF "%CHOICE%"=="4" ( 80 | CALL gradle.bat google:tasks 81 | GOTO :PICK 82 | ) ELSE IF "%CHOICE%"=="5" ( 83 | CALL gradle.bat parallelwebdriver:tasks 84 | GOTO :PICK 85 | GOTO :PICK 86 | ) ELSE IF "%CHOICE%"=="6" ( 87 | CALL gradle.bat commonlib:tasks 88 | GOTO :PICK 89 | ) ELSE IF "%CHOICE%"=="7" ( 90 | ECHO. 91 | SET /P COMMANDS=Enter a space separated set of Gradle tasks: 92 | ECHO. 93 | CALL gradle.bat "%COMMANDS%" -info 94 | ECHO. 95 | GOTO :PICK 96 | ) ELSE IF "%CHOICE%"=="8" ( 97 | CALL gradle.bat --gui 98 | GOTO :END 99 | ) ELSE ( 100 | ECHO Unknown option. Try again. 101 | GOTO :PICK 102 | ) 103 | 104 | ::------------------------------------------------------------------- 105 | :: Functions 106 | ::------------------------------------------------------------------- 107 | 108 | :END 109 | ECHO Closing gradle_run.bat script 110 | FOR /l %%a in (30,-1,1) do (TITLE %TITLETEXT% -- closing in %%as&PING.exe -n 2 -w 1 127.0.0.1>nul) 111 | TITLE Script gradle_run.bat finished 112 | 113 | -------------------------------------------------------------------------------- /parallelwebdriver/src/test/java/webdriver/test/TestHandleCacheTwo.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import org.junit.After; 4 | import org.junit.AfterClass; 5 | import org.junit.Before; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import qa.webdriver.util.WebDriverUtils; 11 | 12 | /** 13 | * This class tests a multi-window handling method that I call "handle cache" 14 | * 15 | * @author Jon Thor Austen 16 | * 17 | */ 18 | public class TestHandleCacheTwo extends WebDriverUtils { 19 | 20 | /** 21 | * Setup web server before loading class 22 | */ 23 | @BeforeClass 24 | public static void setUpTestHandleCacheTwoClass() { 25 | LOGGER.info("Finished setUpTestHandleCacheTwoClass"); 26 | } 27 | 28 | /** 29 | * Load main window handle before tests 30 | */ 31 | public TestHandleCacheTwo() { 32 | classlogger.info("Constructed TestHandleCacheTwo"); 33 | } 34 | 35 | /** 36 | * Start main window handle for tests 37 | */ 38 | @Before 39 | public void setUpTestHandleCacheTwo() { 40 | testXOffset = 550; 41 | initializeRemoteBrowser( "firefox", "localhost", 4444 ); 42 | System.out.println("HandleCacheTwo thread id = " + Thread.currentThread().getId()); 43 | classlogger.info("Finished setUpTestHandleCacheTwo"); 44 | } 45 | 46 | /** 47 | * Tests opening a few windows and then closing them 48 | */ 49 | @Test 50 | public void testHandleCacheTwo() { 51 | classlogger.info("Starting test testHandleCacheTwo" ); 52 | classlogger.info("Loading Window1 contents"); 53 | driver.get( System.getProperty("testProtocol") + "://" + System.getProperty("testDomain") + ":" + 54 | System.getProperty("testPort") + System.getProperty("testUri") ); 55 | waitTimer(4, 500); 56 | 57 | // Open Window2 via Window1 58 | classlogger.info("Opening Window2"); 59 | driver.findElement( By.id("btnNewWindow") ).click(); 60 | String h2 = handleNewWindow(); 61 | waitTimer(2, 500); 62 | 63 | // Open Window3 and Window4 via Window2 64 | //driver.findElement( By.cssSelector("html body a:first-child") ).click(); 65 | classlogger.info("Opening Window3"); 66 | driver.findElement(By.id("w3link")).click(); 67 | String h3 = handleNewWindow(); 68 | waitTimer(2, 500); 69 | driver.switchTo().window( h2 ); 70 | //driver.findElement( By.cssSelector("html body a:last-child") ).click(); 71 | classlogger.info("Opening Window4"); 72 | driver.findElement(By.id("w4link")).click(); 73 | waitTimer(2, 500); 74 | String h4 = handleNewWindow(); 75 | waitTimer(2, 500); 76 | 77 | // close Window4 78 | closeWindowByHandle( h4 ); 79 | updateHandleCache(); 80 | waitTimer(6, 500); 81 | 82 | // close Window3 83 | closeWindowByHandle( h3 ); 84 | updateHandleCache(); 85 | waitTimer(2, 500); 86 | 87 | // close Window2 88 | closeWindowByHandle( h2 ); 89 | updateHandleCache(); 90 | waitTimer(2, 500); 91 | 92 | classlogger.info( "Finished testHandleCacheTwo" ); 93 | } 94 | 95 | /** 96 | * Close main window handle after tests finish 97 | */ 98 | @After 99 | public void tearDown() { 100 | // close main window handle 101 | driver.switchTo().window( mainHandle ); 102 | driver.get("about:about"); 103 | updateHandleCache(); 104 | waitTimer(6, 500); 105 | closeAllBrowserWindows(); 106 | classlogger.info("Finished tearDownTestHandleCacheTwo"); 107 | } 108 | 109 | /** 110 | * Cleanup any remaining objects after unloading class 111 | */ 112 | @AfterClass 113 | public static void tearDownClass() { 114 | LOGGER.info("Finished tearDownTestHandleCacheTwoClass"); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /parallelwebdriver/src/test/java/webdriver/test/TestHandleCacheThree.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import org.junit.After; 4 | import org.junit.AfterClass; 5 | import org.junit.Before; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | import org.openqa.selenium.By; 9 | 10 | import qa.webdriver.util.WebDriverUtils; 11 | 12 | /** 13 | * This class tests a multi-window handling method that I call "handle cache" 14 | * 15 | * @author Jon Thor Austen 16 | * 17 | */ 18 | public class TestHandleCacheThree extends WebDriverUtils { 19 | 20 | /** 21 | * Setup web server before loading class 22 | */ 23 | @BeforeClass 24 | public static void setUpTestHandleCacheTwoClass() { 25 | LOGGER.info("Finished setUpTestHandleCacheThreeClass"); 26 | } 27 | 28 | /** 29 | * Load main window handle before tests 30 | */ 31 | public TestHandleCacheThree() { 32 | classlogger.info("Constructed TestHandleCacheThree"); 33 | } 34 | 35 | /** 36 | * Start main window handle for tests 37 | */ 38 | @Before 39 | public void setUpTestHandleCacheThree() { 40 | testXOffset = 1100; 41 | initializeRemoteBrowser( "firefox", "localhost", 4444 ); 42 | System.out.println("HandleCacheThree thread id = " + Thread.currentThread().getId()); 43 | classlogger.info("Finished setUpTestHandleCacheThree"); 44 | } 45 | 46 | /** 47 | * Tests opening a few windows and then closing them 48 | */ 49 | @Test 50 | public void testHandleCacheTwo() { 51 | classlogger.info("Starting test testHandleCacheThree" ); 52 | classlogger.info("Loading Window1 contents"); 53 | driver.get( System.getProperty("testProtocol") + "://" + System.getProperty("testDomain") + ":" + 54 | System.getProperty("testPort") + System.getProperty("testUri") ); 55 | waitTimer(4, 500); 56 | 57 | // Open Window2 via Window1 58 | classlogger.info("Opening Window2"); 59 | driver.findElement( By.id("btnNewWindow") ).click(); 60 | String h2 = handleNewWindow(); 61 | waitTimer(2, 500); 62 | 63 | // Open Window3 and Window4 via Window2 64 | //driver.findElement( By.cssSelector("html body a:first-child") ).click(); 65 | classlogger.info("Opening Window3"); 66 | driver.findElement(By.id("w3link")).click(); 67 | String h3 = handleNewWindow(); 68 | waitTimer(2, 500); 69 | driver.switchTo().window( h2 ); 70 | //driver.findElement( By.cssSelector("html body a:last-child") ).click(); 71 | classlogger.info("Opening Window4"); 72 | driver.findElement(By.id("w4link")).click(); 73 | waitTimer(2, 500); 74 | String h4 = handleNewWindow(); 75 | waitTimer(2, 500); 76 | 77 | // close Window4 78 | closeWindowByHandle( h4 ); 79 | updateHandleCache(); 80 | waitTimer(6, 500); 81 | 82 | // close Window3 83 | closeWindowByHandle( h3 ); 84 | updateHandleCache(); 85 | waitTimer(2, 500); 86 | 87 | // close Window2 88 | closeWindowByHandle( h2 ); 89 | updateHandleCache(); 90 | waitTimer(2, 500); 91 | 92 | classlogger.info( "Finished testHandleCacheThree" ); 93 | } 94 | 95 | /** 96 | * Close main window handle after tests finish 97 | */ 98 | @After 99 | public void tearDown() { 100 | // close main window handle 101 | driver.switchTo().window( mainHandle ); 102 | driver.get("about:about"); 103 | updateHandleCache(); 104 | waitTimer(6, 500); 105 | closeAllBrowserWindows(); 106 | classlogger.info("Finished tearDownTestHandleCacheThree"); 107 | } 108 | 109 | /** 110 | * Cleanup any remaining objects after unloading class 111 | */ 112 | @AfterClass 113 | public static void tearDownClass() { 114 | LOGGER.info("Finished tearDownTestHandleCacheThreeClass"); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /parallelwebdriver/src/test/java/webdriver/test/TestHandleCacheOne.java: -------------------------------------------------------------------------------- 1 | package webdriver.test; 2 | 3 | import org.junit.After; 4 | import org.junit.AfterClass; 5 | import org.junit.Before; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | import org.openqa.selenium.By; 9 | import qa.webdriver.util.WebDriverUtils; 10 | 11 | /** 12 | * This class tests a multi-window handling method that I call "handle cache" 13 | * 14 | * @author Jon Thor Austen 15 | * 16 | */ 17 | public class TestHandleCacheOne extends WebDriverUtils { 18 | 19 | /** 20 | * Setup web server before loading class 21 | */ 22 | @BeforeClass 23 | public static void setUpTestHandleCacheOneClass() { 24 | LOGGER.info("Finished TestHandleCacheOneClass"); 25 | } 26 | 27 | /** 28 | * Load main window handle before tests 29 | */ 30 | public TestHandleCacheOne() { 31 | classlogger.info("Constructed TestHandleCacheOne"); 32 | } 33 | 34 | /** 35 | * Start main window handle for tests 36 | */ 37 | @Before 38 | public void setUpTestHandleCacheOne() { 39 | testXOffset = 0; 40 | initializeRemoteBrowser( "firefox", System.getProperty("hubUrl") , Integer.parseInt( System.getProperty("hubPort") ) ); 41 | System.out.println("HandleCacheOne thread id = " + Thread.currentThread().getId()); 42 | classlogger.info("Finished setUpTestHandleCacheOne"); 43 | } 44 | 45 | /** 46 | * Tests opening a few windows and then closing them 47 | */ 48 | @Test 49 | public void testHandleCacheOne() { 50 | classlogger.info("Starting test testHandleCacheOne" ); 51 | classlogger.info("Loading Window1 contents"); 52 | driver.get( System.getProperty("testProtocol") + "://" + System.getProperty("testDomain") + ":" + 53 | System.getProperty("testPort") + System.getProperty("testUri") ); 54 | waitTimer(4, 500); 55 | 56 | // Open Window2 via Window1 57 | classlogger.info("Opening Window2"); 58 | driver.findElement( By.id("btnNewWindow") ).click(); 59 | String h2 = handleNewWindow(); 60 | waitTimer(2, 500); 61 | 62 | // Open Window3 and Window4 via Window2 63 | //driver.findElement( By.cssSelector("html body a:first-child") ).click(); 64 | classlogger.info("Opening Window3"); 65 | driver.findElement(By.id("w3link")).click(); 66 | String h3 = handleNewWindow(); 67 | waitTimer(2, 500); 68 | driver.switchTo().window( h2 ); 69 | //driver.findElement( By.cssSelector("html body a:last-child") ).click(); 70 | classlogger.info("Opening Window4"); 71 | driver.findElement(By.id("w4link")).click(); 72 | waitTimer(2, 500); 73 | String h4 = handleNewWindow(); 74 | waitTimer(2, 500); 75 | 76 | // close Window4 77 | closeWindowByHandle( h4 ); 78 | updateHandleCache(); 79 | waitTimer(6, 500); 80 | 81 | // close Window3 82 | closeWindowByHandle( h3 ); 83 | updateHandleCache(); 84 | waitTimer(2, 500); 85 | 86 | // close Window2 87 | closeWindowByHandle( h2 ); 88 | updateHandleCache(); 89 | waitTimer(2, 500); 90 | 91 | classlogger.info( "Finished testHandleCacheOne" ); 92 | } 93 | 94 | /** 95 | * Close main window handle after tests finish 96 | */ 97 | @After 98 | public void tearDownTestHandleCacheOne() { 99 | // close main window handle 100 | driver.switchTo().window( mainHandle ); 101 | driver.get("about:about"); 102 | updateHandleCache(); 103 | waitTimer(6, 500); 104 | closeAllBrowserWindows(); 105 | classlogger.info("Finished tearDownTestHandleCacheOne"); 106 | } 107 | 108 | /** 109 | * Cleanup any remaining objects after unloading class 110 | */ 111 | @AfterClass 112 | public static void tearDownTestHandleCacheOneClass() { 113 | LOGGER.info("Finished tearDownTestHandleCacheOneClass"); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /google/src/main/java/qa/webdriver/util/GoogleSearchPage.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.util; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.Assert; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.ElementNotVisibleException; 8 | import org.openqa.selenium.StaleElementReferenceException; 9 | import org.openqa.selenium.WebElement; 10 | import org.openqa.selenium.support.FindBy; 11 | import org.openqa.selenium.support.PageFactory; 12 | import org.openqa.selenium.support.ui.SlowLoadableComponent; 13 | import org.openqa.selenium.support.ui.SystemClock; 14 | import static qa.webdriver.util.WebDriverUtils.*; 15 | 16 | public class GoogleSearchPage extends SlowLoadableComponent { 17 | 18 | /** 19 | * Inner class 20 | * A fluent API interface that provides methods for calling normal 21 | * page object methods within this class. 22 | */ 23 | public class GSPFluentInterface { 24 | 25 | public GSPFluentInterface(GoogleSearchPage googleSearchPage) { 26 | LOGGER.info("Initialized fluent interface."); 27 | } 28 | 29 | public GSPFluentInterface clickLogo() { 30 | LOGGER.info("Click Google logo."); 31 | WebElement logo = null; 32 | By locator = By.cssSelector( "div.gbqlca" ); 33 | logo = getElementByLocator( locator ); 34 | logo.click(); 35 | return this; 36 | } 37 | 38 | public GSPFluentInterface clickSearchButton() { 39 | searchButton.click(); 40 | return this; 41 | } 42 | 43 | public GSPFluentInterface clickSearchField() { 44 | searchField.click(); 45 | return this; 46 | } 47 | 48 | public GSPFluentInterface selectItem( String match ) { 49 | LOGGER.info("Selecting item in list using fluent API."); 50 | selectInGoogleDropdown( match ); 51 | return this; 52 | } 53 | 54 | public GSPFluentInterface setSearchString( String sstr ) { 55 | By locator = By.id( searchField.getAttribute("id") ); 56 | clearAndType( locator, sstr ); 57 | return this; 58 | } 59 | 60 | /** 61 | * Method: waitForTime 62 | * This method shows an example of a fluent method that provides 63 | * access to a method from an outside class. In this case the 64 | * waitTimer in the utility class. We cannot call waitTimer in 65 | * the middle of a fluent thread and so we provide a fluent method 66 | * here so that a wait can be defined. 67 | */ 68 | public GSPFluentInterface waitForTime( int units, int ms ) { 69 | waitTimer( units, ms ); 70 | return this; 71 | } 72 | 73 | } 74 | 75 | public GSPFluentInterface gspfi; 76 | public static final String searchFieldId = "gbqfq"; 77 | public static final String searchButtonId = "gbqfb"; 78 | //public final String searchFieldCSSLocator = "div#gs_lc0 input#gbqfq.gbqfif"; 79 | //public final String searchButtonCSSLocator = "div#gbqfw #gbqfb.gbqfb"; 80 | public static final String suggestCSSLocator = "table.gstl_0 tbody tr td.gssb_e table.gssb_m tbody tr td.gssb_a div.gsq_a table tbody tr td span"; 81 | 82 | @FindBy(id = searchFieldId ) public WebElement searchField; 83 | @FindBy(id = searchButtonId ) public WebElement searchButton; 84 | 85 | public GoogleSearchPage() { 86 | super( new SystemClock(), DEFAULT_EXPLICIT_WAIT); 87 | this.get(); // SlowLoadableComponent.get() 88 | LOGGER.info("GoogleSearchPage constructor..."); 89 | gspfi = new GSPFluentInterface( this ); // use this only if you want to 90 | } 91 | 92 | public void clickSearchButton() { 93 | if ( searchButton == null ) { 94 | searchButton = getElementByLocator( By.id( searchButtonId ) ); 95 | } else { 96 | try { 97 | searchButton.click(); 98 | } catch ( ElementNotVisibleException e ) { 99 | LOGGER.info( "Element not visible exception clicking search button.\n" + e.getMessage() ); 100 | e.printStackTrace(); 101 | } catch ( Exception e ) { 102 | LOGGER.info( "Exception clicking search button.\n" + e.getMessage() ); 103 | e.printStackTrace(); 104 | } 105 | } 106 | } 107 | 108 | public void clickSearchField() { 109 | if ( searchField == null ) { 110 | searchField = getElementByLocator( By.id( searchFieldId ) ); 111 | } else { 112 | try { 113 | searchField.click(); 114 | } catch ( Exception e ) { 115 | LOGGER.info( "Error clicking search field.\n" + e.getMessage() ); 116 | e.printStackTrace(); 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * Method: isLoaded() 123 | * Overidden method from the LoadableComponent class. 124 | * This method must contain an Assert on visibility of an element in order 125 | * to trigger another call of load() if element is not found. 126 | * @return void 127 | * @throws null 128 | */ 129 | @Override 130 | protected void isLoaded() throws Error { 131 | LOGGER.info("GoogleSearchPage.isLoaded()..."); 132 | boolean loaded = false; 133 | if ( !(searchField == null ) ) { 134 | try { 135 | if ( searchField.isDisplayed() ) { 136 | loaded = true; 137 | } 138 | } catch ( ElementNotVisibleException e ) { 139 | LOGGER.info( "Element may not be displayed yet." ); 140 | } 141 | } 142 | Assert.assertTrue( "Google search field is not yet displayed.", loaded ); 143 | } 144 | 145 | /** 146 | * Method: load 147 | * Overidden method from the LoadableComponent class. 148 | * @return void 149 | * @throws null 150 | */ 151 | @Override 152 | protected void load() { 153 | LOGGER.info("GoogleSearchPage.load()..."); 154 | PageFactory.initElements( driver, this ); // initialize WebElements on page 155 | waitTimer(3, 1000); 156 | } 157 | 158 | /** 159 | * Because of how the page object is initialized, we are using getAttribute here 160 | * @param sstr 161 | * @return void 162 | */ 163 | public void setSearchString( String sstr ) { 164 | By locator = By.id( searchField.getAttribute("id") ); 165 | clearAndType( locator, sstr ); 166 | } 167 | 168 | /** 169 | * Method: withFluent 170 | * Entrypoint for an object that can start a fluent action thread. 171 | * @return GSPFluentInterface 172 | * @throws null 173 | */ 174 | public GSPFluentInterface withFluent() { 175 | return gspfi; 176 | } 177 | 178 | /** 179 | * Method: selectInGoogleDropdown 180 | * Selects element in dropdown using keydowns method (just for fun) 181 | * as long as you typed a string first. 182 | * @return void 183 | * @throws null 184 | */ 185 | public void selectInGoogleDropdown( String match ) { 186 | LOGGER.info("Selecting \"" + match + "\" from Google dropdown."); 187 | List allSuggestions = driver.findElements( By.cssSelector( suggestCSSLocator ) ); 188 | boolean operate = true; 189 | int tries = 0; 190 | while ( operate && tries < 5 ) { 191 | tries +=1; 192 | try { 193 | Thread.sleep(2); 194 | for ( WebElement suggestion : allSuggestions ) { 195 | if ( suggestion.getText().contains( match ) ) { 196 | suggestion.click(); 197 | LOGGER.info("Found item and clicked it."); 198 | Thread.sleep(2); // just to slow it down so human eyes can see it 199 | } 200 | } 201 | operate = false; 202 | } catch ( StaleElementReferenceException e ) { 203 | LOGGER.info("Error while iterating dropdown list:\n" + e.getMessage() ); 204 | //e.printStackTrace(); 205 | } catch ( InterruptedException ie ) { 206 | // do nothing 207 | } 208 | } 209 | LOGGER.info("Finished select in Google dropdown."); 210 | } 211 | 212 | } 213 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #IMPORTANT 2 | This project is no longer maintained. Now, please see this GitHub repo instead: 3 | [selenium-gradle-example](https://github.com/djangofan/selenium-gradle-example) 4 | 5 | # Info 6 | 7 | This is a Java project that can be used as a template (or archetype) to start a WebDriver web browser testing project. I chose to simplify and and implement using simply WebDriver and Gradle.
8 | 9 | I am very much interested in others forking my code and/or letting me know how it can be improved. 10 | 11 | # Versions 12 | 13 | Version 1.0 - March 16, 2013 14 | 15 | 16 | # Project Layout 17 | 18 | Eclipse Root 19 | +--- Project ':root' 20 | +--- Project ':sub-project' 21 | +--- Project ':commonlib' 22 | +--- Project ':google' 23 | +--- Project ':parallelwebdriver' 24 | +--- ... 25 | 26 | # Overview 27 | 28 | 1. Project "sub-project" is a project you add yourself, if you 29 | want. 30 | 2. Project "google" is a RemoteWebDriver JUnit test-suite using 31 | a local Grid server that is capable of running multiple 32 | threads of web browser tests. 33 | 3. Project "parallelwebdriver" is a test of a multi-window 34 | multi-threaded run using a static local website. 35 | 4. Project "commonlib" is a sub-project containing methods 36 | shared between projects. 37 | 5. Project "root" is an 'includeFlat' Gradle-layout-alias to 38 | Eclipse project-root-dir 'WebDriverTestingTemplate'. 39 | 40 | # SubProjects 41 | Links to sub-projects that belong to this project: 42 | 43 | [ParallelWebDriver](https://github.com/djangofan/WebDriverTestingTemplate/blob/master/parallelwebdriver/README.md) 44 | 45 | [Google Example Tests](https://github.com/djangofan/WebDriverTestingTemplate/tree/master/google) 46 | 47 | # Quick Start 48 | Normally, this project would be ran through the Gradle plugin for Eclipse IDE, but I have tried to make it easier 49 | by including a method to run dynamically and directly from the .zip distribution on the command line. 50 | 51 | To try this project without requiring a Java IDE, just make sure you download Gradle 1.4, configure your 52 | GRADLE_HOME environment variable, add %GRADLE_HOME%\bin to your PATH, and then download the .zip distribution 53 | of this project, unzip it, and run the included root/runProjectMenu.bat script. 54 | 55 | # Implemented Features 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 75 | 76 | 77 | 78 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 91 | 92 | 93 | 94 | 96 | 97 | 98 | 99 | 101 | 102 | 103 | 104 | 106 | 107 | 108 | 109 | 112 | 113 | 114 | 115 | 117 | 118 |
FeatureDescription
JUnit basedFor use ONLY with JUnit 4.11 or higher because of the usage of the parameterized capability of JUnit. 64 | This dependency is configured by the Gradle build script.
Parallel runner
using JUnit
A parallel runner using the Gradle maxParallelForks method.
Native automation supportFor use with Sikuli 1.0.1 or higher to test native elements that WebDriver "Action" is unable to 73 | control. This dependency is configured in the Gradle build script. If you implement this however, you 74 | may not be able to use the remote webdriver option in your project.
Uses RemoteWebDriver
JSON Hub Server
I have included an implementation of a WebDriverServer class that starts a RemoteWebDriver JSON 79 | Hub server instance in the BeforeClass method of tests. This server is a static member of the utility 80 | class that the tests extend.
Parameterized data
driven capability
Unit tests are parameterized from a csv file. Can also load tests from XML, XLS, a database, etc.
Logging and ReportingLogs test output to console and to a file using SLF4j/LogBack API, and configured by a logback.xml 89 | file. Will generate reports of JUnit test results at build/reports/test/index.html . Will place a 90 | junit.log file at build/logs/junit.log .
Page Object design
pattern
Uses the WebDriver "page object" design pattern, enhanced by the Selenium "LoadableComponent" 95 | extendable class.
Fluent API design
pattern
Implemented examples of the Fluent API design pattern while retaining capability of 100 | the traditional page object pattern.
Multi-project build
configuration
Implemented multiple project build. The root project has a subproject called "core" and all 105 | subprojects of "core" inherit classes from it.
Run OptionsYou have three different options for running the tests: via the Gradle GUI, via your IDE Gradle 110 | plugin, or via Gradle command line. To run with the JUnit runner in your IDE, you would need to manually 111 | export your project as a normal Java project, because this template does not support that.
Core utility packageAll projects inherit from a "core" project that contains classes where you can store methods 116 | that all of your projects can share between them.
119 | 120 | # Un-implemented Features 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 132 | 133 | 134 | 135 | 139 | 140 |
FeatureDescription
Gradle WrapperDid not choose to implement the Gradle wrapper because I believe that downloading Gradle and 129 | configuring GRADLE_HOME and PATH are easy enough. Also, a manual setup of Gradle gives us more 130 | control using a batch script. Also, the development IDE is usually configured to use the 131 | statically defined Gradle home.
Jar executable optionCreates an uberJar of all projects and subprojects that can be ran by double clicking 136 | the .jar file. If you don't have the file association supporting it, we include a 137 | jarAssociation.bat file to setup the file association on your Windows system. I was planning 138 | to implement this but currently having trouble getting it to work.
141 | 142 | # Configuration And Setup 143 | 144 | #### Eclipse 145 | To get it working on a regular Eclipse 4.2.1 or later, follow these steps: 146 | 147 | 1. Using the "Eclipse Marketplace" settings panel under the 148 | Eclipse "Help" menu, install the Gradle tooling 149 | functionality. You can do it through the "Install New 150 | Software" menu, but it isn't recommended. If Market is 151 | missing from your Eclipse, then add the repo: 152 | http://download.eclipse.org/releases/juno 153 | and then install the "market" and restart Eclipse. 154 | 2. Download the .zip archive of this GitHub project 155 | distribution and unzip it to your workspace. An example: 156 | "C:\Eclipse32\workspace\WebDriverTestingTemplate\" . 157 | 3. Use the Eclipse "Import" function from the Eclipse "File 158 | menu" to import a "Project" of type "Gradle". 159 | 4. Browse using the import wizard to your projects "root" 160 | directory. Then click the "Build model" button. 161 | 5. Check all checkboxes . You could also choose to add all 162 | to your "working set" if you like but it isn't required. 163 | 6. Rebuild the dependencies by right clicking on the project 164 | and then choose Gradle-->Refresh All Dependencies 165 | 7. Right click on your project and choose "Run As-->External 166 | Tools Configuration". Configure a new "clean" and "build" 167 | configuration for running a sub-project (or whatever tasks 168 | you want to execute). 169 | 8. Optionally, you can run this project on the command line 170 | with "gradle google:show google:clean google:build --info" 171 | and it will execute the project unit tests. Also, this 172 | project provides a .bat batch script that does this and 173 | provides a menu of other actions you can execute. 174 | 175 | #### IntelliJ-IDEA 176 | The required Gradle functionality is already built into IntelliJ-IDEA 12.1+ . I think using IDEA is more difficult 177 | but go ahead if you are familiar with it. 178 | 179 | #### Notes 180 | Website of this project:
181 | http://djangofan.github.com/WebDriverTestingTemplate/
182 |
183 | 184 | # FAQ 185 | 186 | 1. If the intellisense in Eclipse doesn't work, make sure you 187 | have added all the .class directories to your Eclipse project 188 | classpath. (See the included .classpath file.) 189 | 2. I use "GitHub GUI" to sync my local project repo to GitHub. 190 | If you fork my project, I would recommend doing it this way 191 | unless you are a Git expert and prefer another way. 192 | 3. 193 | 194 | -------------------------------------------------------------------------------- /commonlib/src/main/java/qa/webdriver/util/WebDriverUtils.java: -------------------------------------------------------------------------------- 1 | package qa.webdriver.util; 2 | 3 | import java.net.MalformedURLException; 4 | import java.net.URL; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import org.openqa.selenium.By; 10 | import org.openqa.selenium.Dimension; 11 | import org.openqa.selenium.JavascriptExecutor; 12 | import org.openqa.selenium.Keys; 13 | import org.openqa.selenium.Point; 14 | import org.openqa.selenium.StaleElementReferenceException; 15 | import org.openqa.selenium.WebDriver; 16 | import org.openqa.selenium.WebElement; 17 | import org.openqa.selenium.chrome.ChromeDriver; 18 | import org.openqa.selenium.firefox.FirefoxDriver; 19 | import org.openqa.selenium.firefox.FirefoxProfile; 20 | import org.openqa.selenium.ie.InternetExplorerDriver; 21 | import org.openqa.selenium.interactions.Actions; 22 | import org.openqa.selenium.remote.DesiredCapabilities; 23 | import org.openqa.selenium.remote.RemoteWebDriver; 24 | import org.openqa.selenium.support.ui.ExpectedConditions; 25 | import org.openqa.selenium.support.ui.FluentWait; 26 | import org.openqa.selenium.support.ui.Wait; 27 | import org.slf4j.LoggerFactory; 28 | import ch.qos.logback.classic.LoggerContext; 29 | import ch.qos.logback.core.util.StatusPrinter; 30 | import qa.webdriver.util.CoreUtils; 31 | 32 | /** 33 | * @author Jon Austen 34 | * 35 | */ 36 | public abstract class WebDriverUtils extends CoreUtils { 37 | 38 | protected WebDriverUtils() { 39 | // do nothing 40 | } 41 | 42 | protected static RemoteWebDriver driver; 43 | public static int DEFAULT_IMPLICIT_WAIT = 30; 44 | public static int DEFAULT_EXPLICIT_WAIT = 10; // seconds that LoadableComponent get() will try to load 45 | protected static String mainHandle = ""; 46 | protected static String mainWindowTitle = ""; 47 | protected static Set handleCache = new HashSet(); 48 | public static int testXOffset = 0; //default value 49 | 50 | public static void clearAndSetValue( By locator, String text ) { 51 | WebElement field = driver.findElement( locator ); 52 | field.clear(); 53 | field.sendKeys( Keys.chord(Keys.CONTROL, "a" ), text ); 54 | } 55 | 56 | public static void clearAndType( By locator, String text ) { 57 | WebElement field = driver.findElement( locator ); 58 | field.clear(); 59 | field.sendKeys( text ); 60 | } 61 | 62 | public static void mouseClickByLocator( By locator ) { 63 | WebElement el = driver.findElement( locator ); 64 | Actions builder = new Actions( driver ); 65 | builder.moveToElement( el ).click( el ); 66 | builder.perform(); 67 | } 68 | 69 | public static void switchToWindowByName( String name ) { 70 | Set windowSet = driver.getWindowHandles(); 71 | for( String handle: windowSet ) { 72 | driver.switchTo().window( handle ); 73 | if ( driver.getTitle().equals( name ) ) { 74 | break; 75 | } 76 | } 77 | } 78 | 79 | public static void clickByIdWithJavascript( String id ) { 80 | JavascriptExecutor js = (JavascriptExecutor)driver; 81 | WebElement element= driver.findElement( By.id( id ) ); 82 | js.executeScript( "arguments[0].click();", element ); 83 | js = null; 84 | } 85 | 86 | public static void closeAllBrowserWindows() { 87 | Set handles = driver.getWindowHandles(); 88 | if ( handles.size() > 1 ) { 89 | LOGGER.info("Closing " + handles.size() + " window(s)."); 90 | for ( String windowId : handles ) { 91 | LOGGER.info("-- Closing window handle: " + windowId ); 92 | // this can hang if you replaced the DOM with a document.write before calling this 93 | driver.switchTo().window( windowId ).close(); 94 | } 95 | } else if ( handles.size()==1 ) { 96 | LOGGER.info("Closing last open window."); 97 | } else { 98 | LOGGER.info("There were no window handles to close."); 99 | } 100 | driver.quit(); // this quit is critical, otherwise last window will hang open 101 | } 102 | 103 | public static void closeWindowByHandle( String windowHandle ) { 104 | driver.switchTo().window( windowHandle ); 105 | LOGGER.info("Closing window with title \"" + driver.getTitle() + "\"." ); 106 | driver.close(); 107 | } 108 | /** 109 | * Print internal Logger status 110 | */ 111 | public static void returnLoggerState() { 112 | LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 113 | StatusPrinter.print(lc); 114 | } 115 | 116 | /** 117 | * Loops to determine if WebDriver.getWindowHandles() returns any 118 | * additional windows that the allHandles cache does not currently 119 | * contain. If new windows are found, switch to latest window and 120 | * update allHandles cache. 121 | */ 122 | public static String handleNewWindow() { 123 | String newHandle = ""; 124 | printHandles(); 125 | Set updatedHandles = driver.getWindowHandles(); 126 | if ( updatedHandles.size() <= handleCache.size() ) { 127 | mainHandle = ""; 128 | throw new IllegalStateException("This method handleNewWindow is not appropriate\n" + 129 | "in this case. You are probably looking for the\n"+ 130 | "use of the updateHandleCache method."); 131 | } else { 132 | if ( !updatedHandles.isEmpty() ) { 133 | for ( String windowId : updatedHandles ) { 134 | if ( !windowId.equals( mainHandle ) ) { // for all windows except main window 135 | if ( !handleCache.contains( windowId) ) { // for child windows not in allHandles cache 136 | newHandle = windowId; // set value of newly found window handle 137 | LOGGER.info("-- Open window handle: " + newHandle + " (new window)" ); 138 | } 139 | } 140 | } 141 | if ( !newHandle.equals("") ) { // outside loop so it catches latest window handle if there are multiple 142 | LOGGER.info("Switch to new window."); 143 | driver.switchTo().window( newHandle ); // switch to new window handle 144 | } 145 | } else { 146 | mainHandle = ""; 147 | throw new IllegalStateException("No browser window handles are open."); 148 | } 149 | } 150 | handleCache = updatedHandles; // updates remembered set of open windows 151 | return newHandle; 152 | } 153 | 154 | public static void updateHandleCache() { 155 | LOGGER.info("Updating cache of window handles..."); 156 | printHandles(); 157 | Set updatedHandles = driver.getWindowHandles(); 158 | if ( !updatedHandles.isEmpty() ) { 159 | if ( updatedHandles.size() > handleCache.size() ) { 160 | LOGGER.info( "Window handle number increased to: " + updatedHandles.size() ); 161 | } else if ( updatedHandles.size() == handleCache.size() ) { 162 | LOGGER.info( "Window handle number is unchanged from: " + updatedHandles.size() ); 163 | } else { 164 | LOGGER.info( "Window handle number decreased to: " + updatedHandles.size() ); 165 | } 166 | } else { 167 | mainHandle = null; 168 | throw new IllegalStateException("No browser window handles are open."); 169 | } 170 | handleCache = updatedHandles; // updates remembered set of open windows 171 | } 172 | 173 | public static void printHandles() { 174 | LOGGER.info( "Open windows:" ); 175 | for ( String windowId : handleCache ) { 176 | LOGGER.info( "-- Open window handle: " + windowId ); 177 | if ( windowId.equals( mainHandle ) ) { 178 | LOGGER.info(" (main handle)"); 179 | } 180 | } 181 | } 182 | 183 | public static void initializeLocalBrowser( String type ) { 184 | if ( type.equalsIgnoreCase( "firefox" ) ) { 185 | FirefoxProfile profile = new FirefoxProfile(); 186 | profile.setPreference("network.proxy.http", "localhost"); 187 | profile.setPreference("network.proxy.http_port", "3128"); 188 | driver = new FirefoxDriver( profile ); 189 | } else if ( type.equalsIgnoreCase( "internetExplorer" ) ) { 190 | driver = new InternetExplorerDriver(); 191 | } 192 | else if ( type.equalsIgnoreCase( "chrome" ) ) { 193 | driver = new ChromeDriver(); 194 | } else { 195 | LOGGER.info( "Invalid browser type. Cannot initialize." ); 196 | } 197 | driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.MILLISECONDS ); 198 | positionMainHandle(); 199 | } 200 | 201 | public static void initializeRemoteBrowser( String type, String host, int port ) { 202 | DesiredCapabilities dc = new DesiredCapabilities(); 203 | dc.setCapability( "takesScreenshot", false ); 204 | dc.setCapability( "webdriver.remote.quietExceptions", false ); 205 | try { 206 | if ( type.equalsIgnoreCase( "firefox" ) ) { 207 | dc.setBrowserName("firefox"); 208 | driver = new RemoteWebDriver( new URL("http://" + host + ":" + port + "/wd/hub"), dc ); 209 | 210 | } else if ( type.equalsIgnoreCase( "ie" ) ) { 211 | dc.setBrowserName("internetExplorer"); 212 | driver = new RemoteWebDriver( new URL("http://" + host + ":" + port + "/wd/hub"), dc ); 213 | } 214 | else if ( type.equalsIgnoreCase( "chrome" ) ) { 215 | dc.setBrowserName("chrome"); 216 | driver = new RemoteWebDriver( new URL("http://" + host + ":" + port + "/wd/hub"), dc ); 217 | } else { 218 | LOGGER.info( "Invalid browser type. Cannot initialize." ); 219 | } 220 | } catch ( MalformedURLException e ) { 221 | e.printStackTrace(); 222 | } 223 | driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.MILLISECONDS ); 224 | positionMainHandle(); 225 | } 226 | 227 | private static void positionMainHandle() { 228 | handleCache = driver.getWindowHandles(); 229 | if ( handleCache.size() == 0 ) { 230 | mainHandle = ""; 231 | throw new IllegalStateException("No browser window handles are open.\n" + 232 | "Browser is uninitialized."); 233 | } else if ( handleCache.size() > 1 ) { 234 | mainHandle = ""; 235 | throw new IllegalStateException("More than one browser window handle is open.\n" + 236 | "Please close all browsers and restart test."); 237 | } else { 238 | mainHandle = driver.switchTo().defaultContent().getWindowHandle(); 239 | mainWindowTitle = driver.switchTo().defaultContent().getTitle(); 240 | int fromLeft = Integer.parseInt( System.getProperty("windowXPosition") ); 241 | int fromTop = Integer.parseInt( System.getProperty("windowYPosition") ); 242 | int width = Integer.parseInt( System.getProperty("windowWidth") ); 243 | int height = Integer.parseInt( System.getProperty("windowHeight") ); 244 | setWindowPosition( mainHandle, width, height, fromLeft + testXOffset, fromTop ); 245 | } 246 | } 247 | 248 | public static void setWindowPosition(String handle, int width, int height, int fleft, int ftop) { 249 | driver.switchTo().window( handle ).manage().window().setPosition( new Point(fleft, ftop) ); 250 | driver.switchTo().window( handle ).manage().window().setSize( new Dimension( width, height) ); 251 | //TODO add a javascript executor to get window focus 252 | } 253 | 254 | public static WebElement getElementByLocator( final By locator ) { 255 | LOGGER.info( "Get element by locator: " + locator.toString() ); 256 | final long startTime = System.currentTimeMillis(); 257 | Wait wait = new FluentWait( driver ) 258 | .withTimeout(30, TimeUnit.SECONDS) 259 | .pollingEvery(5, TimeUnit.SECONDS) 260 | .ignoring( StaleElementReferenceException.class ) ; 261 | int tries = 0; 262 | boolean found = false; 263 | WebElement we = null; 264 | while ( (System.currentTimeMillis() - startTime) < 91000 ) { 265 | LOGGER.info( "Searching for element. Try number " + (tries++) ); 266 | try { 267 | we = wait.until( ExpectedConditions.visibilityOfElementLocated( locator ) ); 268 | found = true; 269 | break; 270 | } catch ( StaleElementReferenceException e ) { 271 | LOGGER.info( "Stale element: \n" + e.getMessage() + "\n"); 272 | } 273 | } 274 | long endTime = System.currentTimeMillis(); 275 | long totalTime = endTime - startTime; 276 | if ( found ) { 277 | LOGGER.info("Found element after waiting for " + totalTime + " milliseconds." ); 278 | } else { 279 | LOGGER.info( "Failed to find element after " + totalTime + " milliseconds." ); 280 | } 281 | return we; 282 | } 283 | 284 | public void showMessageInBrowser( String message ) { 285 | message = "Message" + message + ""; 286 | String script = "document.write( '" + message + "' );"; 287 | ((JavascriptExecutor)driver).executeScript( script ); 288 | } 289 | 290 | 291 | } 292 | -------------------------------------------------------------------------------- /parallelwebdriver/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /commonlib/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /google/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | --------------------------------------------------------------------------------