├── .gitignore ├── src └── test │ └── java │ └── com │ └── eviltester │ └── webdriver │ ├── overview │ ├── TestEnv.java │ ├── YoutubeVideoTest.java │ └── BasicPage.java │ ├── basicsOfPageObjects │ ├── SiteConfig.java │ ├── UsingPageObjectsTest.java │ └── BasicWebPage.java │ ├── basics │ └── AFirstChromeTest.java │ ├── basicsOfJunit │ └── BeforeAfterChromeTest.java │ ├── browsers │ ├── ConfigurableFirefoxTest.java │ └── ConfigurableChromeTest.java │ └── basicsOfSynchronization │ ├── WaitingForStateTest.java │ └── WaitingInsteadOfAssertionTest.java ├── .github └── workflows │ └── build.yml ├── LICENSE ├── README.md ├── install_notes.md ├── pom.xml └── speedrun_install_checklist.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target 3 | *.iml 4 | /.idea 5 | /tools 6 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/overview/TestEnv.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.overview; 2 | 3 | public class TestEnv { 4 | public static final String DOMAIN = "https://testpages.eviltester.com"; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfPageObjects/SiteConfig.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfPageObjects; 2 | 3 | public class SiteConfig { 4 | 5 | public static String getDomain(){ 6 | return "https://testpages.eviltester.com"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basics/AFirstChromeTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basics; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.WebDriver; 7 | import org.openqa.selenium.WebElement; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | 10 | public class AFirstChromeTest { 11 | @Test 12 | public void myFirstWebDriverTest(){ 13 | 14 | WebDriver driver = new ChromeDriver(); 15 | 16 | driver.get( 17 | "https://testpages.eviltester.com/pages/basics/basic-web-page/" 18 | ); 19 | 20 | WebElement button = driver.findElement(By.id("button1")); 21 | 22 | Assertions.assertEquals("Click Me", button.getText()); 23 | 24 | driver.quit(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfPageObjects/UsingPageObjectsTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfPageObjects; 2 | 3 | import org.junit.jupiter.api.*; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.chrome.ChromeDriver; 6 | 7 | public class UsingPageObjectsTest { 8 | 9 | static WebDriver driver; 10 | private BasicWebPage page; 11 | 12 | @BeforeAll 13 | public static void initiateWebDriver(){ 14 | driver = new ChromeDriver(); 15 | } 16 | 17 | @BeforeEach 18 | public void loadPage(){ 19 | page = new BasicWebPage(driver); 20 | page.get(); 21 | } 22 | 23 | @Test 24 | public void pageHasCorrectButtonText(){ 25 | Assertions.assertEquals(page.getButtonText(), "Click Me"); 26 | } 27 | 28 | @AfterAll 29 | public static void closeWebDriver(){ 30 | driver.quit(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | workflow_dispatch: 4 | push: 5 | schedule: 6 | - cron: '0 1 * * 6' # weekly check that it still works 7 | 8 | env: 9 | BROWSER_STATE: Headless 10 | 11 | jobs: 12 | compile-and-test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | # https://github.com/actions/checkout 16 | - name: Download repository 17 | uses: actions/checkout@v5 18 | 19 | # https://github.com/actions/setup-java 20 | - name: Set up JDK 21 21 | uses: actions/setup-java@v5 22 | with: 23 | distribution: 'temurin' 24 | java-version: 21 25 | 26 | - name: Test with Maven (and xvfb) 27 | uses: GabrielBB/xvfb-action@v1 28 | with: 29 | run: mvn -Dwebdriver.chrome.logfile=${{ github.workspace }}/chromedriver.log -Dwebdriver.chrome.verboseLogging=true test 30 | 31 | - name: Show logs 32 | if: failure() 33 | run: | 34 | cat ${{ github.workspace }}/chromedriver.log 35 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfJunit/BeforeAfterChromeTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfJunit; 2 | 3 | import org.junit.jupiter.api.*; 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | 9 | public class BeforeAfterChromeTest { 10 | 11 | static WebDriver driver; 12 | 13 | @BeforeAll 14 | public static void initiateWebDriver(){ 15 | driver = new ChromeDriver(); 16 | } 17 | 18 | @BeforeEach 19 | public void loadPage(){ 20 | driver.get( 21 | "https://testpages.eviltester.com/pages/basics/basic-web-page/" 22 | ); 23 | } 24 | 25 | @Test 26 | public void buttonHasCorrectText(){ 27 | WebElement button = driver.findElement(By.id("button1")); 28 | 29 | Assertions.assertEquals("Click Me", button.getText()); 30 | } 31 | 32 | @AfterAll 33 | public static void closeWebDriver(){ 34 | driver.quit(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Alan Richardson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/overview/YoutubeVideoTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.overview; 2 | 3 | import org.junit.jupiter.api.*; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.chrome.ChromeDriver; 6 | 7 | /* 8 | This was the test code created for: 9 | 10 | https://youtu.be/bQ7y9-Y2U2c 11 | 12 | The supporting video for: 13 | 14 | https://testpages.eviltester.com/reference/automating/webdriver/webdriver-java/ 15 | */ 16 | 17 | public class YoutubeVideoTest { 18 | 19 | static WebDriver driver; 20 | BasicPage page; 21 | 22 | @BeforeAll 23 | public static void startUp(){ 24 | driver = new ChromeDriver(); 25 | } 26 | 27 | @BeforeEach 28 | public void gotoPage(){ 29 | page = new BasicPage(driver); 30 | page.get(); 31 | } 32 | 33 | @Test 34 | public void myFirstTest(){ 35 | Assertions.assertEquals( 36 | "A paragraph of text", 37 | page.getParaText() 38 | ); 39 | } 40 | 41 | @Test 42 | public void canClickButton(){ 43 | page.clickMeButton().click(); 44 | page.waitUntilMessageShown(); 45 | 46 | Assertions.assertEquals( 47 | "You clicked the button!", 48 | page.getSuccessMessage().getText() 49 | ); 50 | } 51 | 52 | @AfterAll 53 | public static void tearDown(){ 54 | driver.quit(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/browsers/ConfigurableFirefoxTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.browsers; 2 | 3 | import com.eviltester.webdriver.basicsOfPageObjects.BasicWebPage; 4 | import org.junit.jupiter.api.AfterAll; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.BeforeAll; 7 | import org.junit.jupiter.api.Test; 8 | import org.openqa.selenium.WebDriver; 9 | import org.openqa.selenium.firefox.FirefoxDriver; 10 | import org.openqa.selenium.firefox.FirefoxOptions; 11 | 12 | public class ConfigurableFirefoxTest { 13 | 14 | /** 15 | The following code is for the Firefox Driver. 16 | */ 17 | 18 | static WebDriver driver; 19 | 20 | @BeforeAll 21 | public static void initiateWebDriver(){ 22 | FirefoxOptions options = new FirefoxOptions(); 23 | if(System.getenv(). 24 | getOrDefault("BROWSER_STATE","show"). 25 | equals("Headless")){ 26 | options.addArguments("--headless"); 27 | } 28 | 29 | driver = new FirefoxDriver(options); 30 | } 31 | 32 | @Test 33 | public void startWebDriver(){ 34 | 35 | BasicWebPage page = new BasicWebPage(driver); 36 | page.get(); 37 | 38 | Assertions.assertEquals( 39 | "Click Me", 40 | page.getButton().getText() 41 | ); 42 | 43 | } 44 | 45 | @AfterAll 46 | public static void closeWebDriver(){ 47 | driver.quit(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfPageObjects/BasicWebPage.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfPageObjects; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.ui.ExpectedCondition; 7 | import org.openqa.selenium.support.ui.ExpectedConditions; 8 | 9 | public class BasicWebPage { 10 | 11 | private final WebDriver driver; 12 | 13 | // locators 14 | public final By CLICK_ME_BUTTON = By.id("button1"); 15 | public final By CLICK_MESSAGE = By.id("click-message"); 16 | 17 | public BasicWebPage(WebDriver driver) { 18 | this.driver = driver; 19 | } 20 | 21 | // navigators 22 | public void get() { 23 | driver.get(SiteConfig.getDomain() + "/pages/basics/basic-web-page/"); 24 | } 25 | 26 | // element accessors 27 | public WebElement getButton(){ 28 | return driver.findElement(CLICK_ME_BUTTON); 29 | } 30 | 31 | // helpers 32 | public String getButtonText() { 33 | return getButton().getText(); 34 | } 35 | 36 | public WebElement getClickMessage() { 37 | return driver.findElement(CLICK_MESSAGE); 38 | } 39 | 40 | public ExpectedCondition showsMessage() { 41 | return ExpectedConditions.not(ExpectedConditions.textToBe(CLICK_MESSAGE, "")); 42 | } 43 | 44 | public ExpectedCondition successMessageNotShown() { 45 | return ExpectedConditions.textToBe(CLICK_MESSAGE, ""); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/overview/BasicPage.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.overview; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.support.ui.ExpectedConditions; 7 | import org.openqa.selenium.support.ui.WebDriverWait; 8 | 9 | import java.time.Duration; 10 | 11 | public class BasicPage { 12 | 13 | private final WebDriver driver; 14 | 15 | // locators 16 | public static final By SUCCESS_MESSAGE = By.id("click-message"); 17 | 18 | public BasicPage(WebDriver driver) { 19 | this.driver = driver; 20 | } 21 | 22 | // navigator 23 | public void get() { 24 | driver.get(TestEnv.DOMAIN + "/pages/basics/basic-web-page/"); 25 | } 26 | 27 | // element accessors 28 | public WebElement clickMeButton() { 29 | return driver.findElement(By.id("button1")); 30 | } 31 | 32 | public WebElement getSuccessMessage() { 33 | return driver.findElement(SUCCESS_MESSAGE); 34 | } 35 | 36 | // synchronization 37 | public void waitUntilMessageShown() { 38 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); 39 | 40 | wait.until( 41 | ExpectedConditions.not( 42 | ExpectedConditions.textToBe( 43 | SUCCESS_MESSAGE, "" 44 | ) 45 | )); 46 | } 47 | 48 | // functional helper 49 | public String getParaText() { 50 | return driver.findElement(By.id("para1")).getText(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/browsers/ConfigurableChromeTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.browsers; 2 | 3 | import com.eviltester.webdriver.basicsOfPageObjects.BasicWebPage; 4 | import org.junit.jupiter.api.*; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.chrome.ChromeOptions; 8 | 9 | public class ConfigurableChromeTest { 10 | 11 | /** 12 | The following code is for the Chrome Driver. 13 | */ 14 | 15 | static WebDriver driver; 16 | 17 | @BeforeAll 18 | public static void initiateWebDriver(){ 19 | ChromeOptions options = new ChromeOptions(); 20 | if(System.getenv(). 21 | getOrDefault("BROWSER_STATE","show"). 22 | equals("Headless")){ 23 | options.addArguments("--headless"); 24 | } 25 | 26 | driver = new ChromeDriver(options); 27 | } 28 | 29 | 30 | @Test 31 | public void startWebDriver(){ 32 | 33 | BasicWebPage page = new BasicWebPage(driver); 34 | page.get(); 35 | 36 | Assertions.assertEquals( 37 | "Click Me", 38 | page.getButton().getText() 39 | ); 40 | 41 | } 42 | 43 | @AfterAll 44 | public static void closeWebDriver(){ 45 | driver.quit(); 46 | } 47 | 48 | /* 49 | 50 | if https://testpages.eviltester.com or https://testpages.herokuapp.com is not working then you can download the 51 | test pages app from github 52 | 53 | https://github.com/eviltester/TestingApp/tree/master/java/testingapps/seleniumtestpages 54 | 55 | The herokuapp and github release are maintained. 56 | 57 | If you want to learn more about Selenium WebDriver then check out my online courses: 58 | 59 | https://eviltester.com/courses 60 | 61 | */ 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfSynchronization/WaitingForStateTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfSynchronization; 2 | 3 | import com.eviltester.webdriver.basicsOfPageObjects.BasicWebPage; 4 | import org.junit.jupiter.api.*; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.support.ui.ExpectedConditions; 9 | import org.openqa.selenium.support.ui.WebDriverWait; 10 | 11 | import java.time.Duration; 12 | 13 | public class WaitingForStateTest { 14 | 15 | static WebDriver driver; 16 | private BasicWebPage page; 17 | 18 | @BeforeAll 19 | public static void initiateWebDriver(){ 20 | driver = new ChromeDriver(); 21 | } 22 | 23 | @BeforeEach 24 | public void loadPage(){ 25 | page = new BasicWebPage(driver); 26 | page.get(); 27 | } 28 | 29 | @Test 30 | public void buttonHasCorrectText(){ 31 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 32 | 33 | wait.until(ExpectedConditions.elementToBeClickable(page.getButton())); 34 | 35 | Assertions.assertEquals("Click Me", page.getButtonText()); 36 | } 37 | 38 | @Test 39 | public void buttonHasCorrectTextSyncBy(){ 40 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 41 | 42 | wait.until(ExpectedConditions.elementToBeClickable(page.CLICK_ME_BUTTON)); 43 | 44 | Assertions.assertEquals("Click Me", page.getButtonText()); 45 | } 46 | 47 | @Test 48 | public void clickingButtonShowsMessage(){ 49 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 50 | 51 | wait.until(ExpectedConditions.elementToBeClickable(page.CLICK_ME_BUTTON)); 52 | page.getButton().click(); 53 | 54 | WebElement message = page.getClickMessage(); 55 | 56 | // this might be flaky so we can wait for condition 57 | String successMessage = "You clicked the button!"; 58 | wait.until(ExpectedConditions.textToBe(page.CLICK_MESSAGE, successMessage)); 59 | Assertions.assertEquals(successMessage, message.getText()); 60 | } 61 | 62 | 63 | @AfterAll 64 | public static void closeWebDriver(){ 65 | driver.quit(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Start Using Selenium WebDriver 2 | =========================== 3 | 4 | [![build status](https://github.com/eviltester/startUsingSeleniumWebDriver/actions/workflows/build.yml/badge.svg)](https://github.com/eviltester/startUsingSeleniumWebDriver/actions) 5 | 6 | Simple start example for Selenium 4 with java and JUnit 5. 7 | 8 | - For previous versions of WebDriver and JUnit see the releases page. 9 | 10 | It has the basic startup and configuration for a test using Chrome Driver. 11 | 12 | Supporting text description of the contents of this repo can be found: 13 | 14 | - https://testpages.eviltester.com/reference/automating/webdriver/webdriver-java/ 15 | 16 | The pages used as the system under test are: 17 | 18 | - https://testpages.eviltester.com 19 | 20 | ## Pre-Requisites 21 | 22 | Pre-requisites are ([use quick start guide to install these](https://github.com/eviltester/startUsingJavaJUnit5/blob/main/speedrun_install_java_checklist.md)): 23 | 24 | - a Java SDK 25 | - maven 26 | - and and IDE Install. 27 | 28 | The code uses JUnit 5 so you can follow the Quick Start Guide in the "[Getting Started with JUnit 5 repo](https://github.com/eviltester/startUsingJavaJUnit5)" 29 | 30 | - [Quick start guide is here](https://github.com/eviltester/startUsingJavaJUnit5/blob/main/speedrun_install_java_checklist.md) 31 | 32 | ## Start By 33 | 34 | Clone or download the repo as a zip. 35 | 36 | From the unzipped top level directory containing the 'pom.xml' file, you can run the test using: 37 | 38 | `mvn test` 39 | 40 | And can run it using headless mode by setting the environment variable `BROWSER_STATE` to have the value "`Headless`" 41 | 42 | e.g. 43 | 44 | ``` 45 | BROWSER_STATE=Headless mvn test 46 | ``` 47 | 48 | ## Use the code 49 | 50 | Open the project in Intellij by opening the folder containing the 'pom.xml' or open the 'pom.xml'. 51 | 52 | ## Github Actions 53 | 54 | The repo also has [Github actions](https://github.com/eviltester/startUsingJavaJUnit5/blob/main/.github/workflows/build.yml) to run the test in headless mode periodically. 55 | 56 | ## About Selenium WebDriver 4 57 | 58 | This uses Selenium 4. 59 | 60 | Selenium 4 comes with a builtin WebDriver Manager 61 | 62 | https://www.selenium.dev/blog/2022/introducing-selenium-manager/ 63 | 64 | This will automatically download the drivers required to allow Selenium to use the chosen webdriver. 65 | 66 | e.g. if you instantiate a `new ChromeDriver()` the WebDriver Manager will download the drivers for 67 | Chrome and run the tests against Chrome. 68 | 69 | You just need to download and have Chrome installed. 70 | 71 | Similarly, with Firefox and Edge, just download the browser and Selenium will download the correct driver. 72 | 73 | 74 | -------------------------------------------------------------------------------- /install_notes.md: -------------------------------------------------------------------------------- 1 | Installation on Windows 10 Notes: 2 | ================================= 3 | 4 | * Using VM from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ 5 | * `IEUser` / `Passw0rd!` 6 | * https://az792536.vo.msecnd.net/vms/release_notes_license_terms_8_1_15.pdf 7 | * used Chocolatey for JDK, IntelliJ, ChromeDriver and GeckoDriver Installs 8 | 9 | 10 | Installation on XP Notes: 11 | ========================= 12 | 13 | - I installed using the Windows XP VM from modern.ie, 14 | with Java 1.7, maven 3.2.3, Webdriver 2.43.1, IntelliJ 13.1.5 15 | 16 | - need to use JDK 1.7, JDK 1.8 reports a warning on Windows XP 17 | 18 | - download a different text editor to edit the pom.xml (I used notepad++) 19 | - You may need to download a better editor than notepad.exe I use notepad++ 20 | - download notepad ++ from 21 | http://notepad-plus-plus.org/download 22 | 23 | - You need to 'unblock' Java and the IDE etc. 24 | for the Windows Firewall as you run through the checklist. 25 | Do this, otherwise they won't be able to work 26 | 27 | - Edit SDK by right clicking and choosing "Open Module Settings", 28 | then edit the SDK for the Project and press [OK] 29 | - choose the location of the Java JDK you installed 30 | (sometimes you don't have to do this) 31 | 32 | + After test passes in the IDE - ignore the Info Message from WebDriver 33 | 34 | "Oct 07, 2014 10:40:36 AM org.openqa.selenium.os.UnixProcess$SeleniumWatchDog destroyHarder 35 | INFO: Command failed to close cleanly. Destroying forcefully (v2). 36 | org.openqa.selenium.os.UnixProcess$SeleniumWatchDog@da44a7 37 | 38 | Process finished with exit code 0 39 | " 40 | It worked fine 41 | 42 | 43 | Installation on Mac Notes: 44 | ========================== 45 | 46 | - I installed using a VM with OS X Mavericks, then Java 1.8, 47 | maven 3.2.3, Webdriver 2.43.1, IntelliJ 13.1.5 48 | 49 | - slightly different order of the install than Windows because: 50 | I was prompted to install JDK when I typed "javac -version" so 51 | I followed the instructions at that point. 52 | 53 | I didn't need to install Firefox early because I could use the 54 | build in Safari browser to download software. 55 | 56 | I didn't need to install a separate text editor as the build in 57 | handled the pom.xml file fine. 58 | 59 | - with Maven 60 | - on mac, downloaded the zip 61 | - I didn't have a /usr/local so I had to "sudo mkdir /usr/local" 62 | - then I extracted the contents into an apache-maven-3.2.3 directory 63 | in /usr/local (I probably should have created an /apache-maven 64 | directory as well, but I didn't 65 | 66 | then I created all the exports in the terminal 67 | 68 | export M2_HOME=/usr/local/apache-maven-3.2.3 69 | export M2=$M2_HOME/bin 70 | export PATH=$M2:$PATH 71 | 72 | when I tried mvn -version it recognised maven but JAVA_HOME 73 | wasn't setup so I had to 74 | 75 | export JAVA_HOME="$(/usr/libexec/java_home)" 76 | 77 | Then it worked 78 | 79 | Then open a new tab and vi ~/.bash_profile and copy and paste 80 | in all the exports 81 | 82 | then create a new tab and "mvn --version" to check that it worked 83 | 84 | - Firefox 85 | searched for "firefox" then download from the mozilla.org site 86 | ran it 87 | nice overlapping dialogs that I had to deal with 88 | 89 | - when I ran "mvn test -Dtest=MyFirstTest", my wifi connection dropped 90 | in the middle, but I restarted wifi and ran the mvn command again 91 | and it completed fine - one reason to use Maven 92 | -------------------------------------------------------------------------------- /src/test/java/com/eviltester/webdriver/basicsOfSynchronization/WaitingInsteadOfAssertionTest.java: -------------------------------------------------------------------------------- 1 | package com.eviltester.webdriver.basicsOfSynchronization; 2 | 3 | import com.eviltester.webdriver.basicsOfPageObjects.BasicWebPage; 4 | import org.junit.jupiter.api.*; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.support.ui.ExpectedConditions; 9 | import org.openqa.selenium.support.ui.WebDriverWait; 10 | 11 | import java.time.Duration; 12 | 13 | public class WaitingInsteadOfAssertionTest { 14 | 15 | static WebDriver driver; 16 | private BasicWebPage page; 17 | 18 | @BeforeAll 19 | public static void initiateWebDriver(){ 20 | driver = new ChromeDriver(); 21 | } 22 | 23 | @BeforeEach 24 | public void loadPage(){ 25 | page = new BasicWebPage(driver); 26 | page.get(); 27 | } 28 | 29 | @Test 30 | public void clickingButtonShowsMessageWait(){ 31 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 32 | 33 | wait.until(ExpectedConditions.elementToBeClickable(page.CLICK_ME_BUTTON)); 34 | page.getButton().click(); 35 | 36 | WebElement message = page.getClickMessage(); 37 | 38 | // this might be flaky 39 | // Assertions.assertEquals("You clicked the button!", message.getText()); 40 | // instead wait for the text to appear and disappear 41 | // no asserts are really needed but we can add them so that reviewers know the waits 42 | // are not just for synchronisation 43 | String successMessage = "You clicked the button!"; 44 | 45 | wait.until(ExpectedConditions.textToBe(page.CLICK_MESSAGE, successMessage)); 46 | Assertions.assertEquals(successMessage, message.getText()); 47 | 48 | wait.until(ExpectedConditions.textToBe(page.CLICK_MESSAGE, "")); 49 | Assertions.assertEquals("", message.getText()); 50 | } 51 | 52 | @Test 53 | public void clickingButtonShowsMessageSyncWaitDifferentFromAssert(){ 54 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 55 | 56 | wait.until(ExpectedConditions.elementToBeClickable(page.CLICK_ME_BUTTON)); 57 | page.getButton().click(); 58 | 59 | WebElement message = page.getClickMessage(); 60 | 61 | // The asserts are different from the wait conditions 62 | // so both are necessary now 63 | String successMessage = "You clicked the button!"; 64 | 65 | //wait until a message is shown 66 | wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(page.CLICK_MESSAGE, ""))); 67 | Assertions.assertEquals(successMessage, message.getText()); 68 | 69 | // wait until the success message is not shown 70 | wait.until(ExpectedConditions.not(ExpectedConditions.textToBe(page.CLICK_MESSAGE, successMessage))); 71 | Assertions.assertEquals("", message.getText()); 72 | } 73 | 74 | @Test 75 | public void clickingButtonShowsMessagePageAbstraction(){ 76 | WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); 77 | 78 | wait.until(ExpectedConditions.elementToBeClickable(page.CLICK_ME_BUTTON)); 79 | page.getButton().click(); 80 | 81 | WebElement message = page.getClickMessage(); 82 | 83 | /* 84 | By moving the wait conditions into the page abstraction 85 | the test is more readable, and we maintain sync and assert 86 | conditions separately 87 | */ 88 | wait.until(page.showsMessage()); 89 | Assertions.assertEquals("You clicked the button!", message.getText()); 90 | 91 | wait.until(page.successMessageNotShown()); 92 | Assertions.assertEquals("", message.getText()); 93 | } 94 | 95 | @AfterAll 96 | public static void closeWebDriver(){ 97 | driver.quit(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | eviltester.com 8 | startUsingSeleniumWebDriver 9 | 1.0 10 | 11 | 12 | UTF-8 13 | 14 | 5.14.0 15 | 16 | 17 | 4.38.0 18 | 19 | 20 | 21 21 | 21 22 | 23 | 24 | 3.2.5 25 | 26 | 27 | 4.0.0-M14 28 | 3.2.5 29 | 30 | 31 | 39 | 40 | 41 | 42 | 47 | 48 | org.seleniumhq.selenium 49 | selenium-java 50 | ${selenium-webdriver-version} 51 | test 52 | 53 | 54 | 55 | org.junit.jupiter 56 | junit-jupiter 57 | ${junit.jupiter.version} 58 | test 59 | 60 | 61 | 62 | 63 | 64 | 69 | 70 | org.apache.maven.plugins 71 | maven-surefire-plugin 72 | ${maven.surefire.version} 73 | 74 | 75 | 79 | 80 | org.apache.maven.plugins 81 | maven-site-plugin 82 | ${maven-site-plugin.version} 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 95 | 96 | org.apache.maven.plugins 97 | maven-surefire-report-plugin 98 | ${maven.surefire.report.version} 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /speedrun_install_checklist.md: -------------------------------------------------------------------------------- 1 | 2 | # Generic Selenium WebDriver Install Speedrun checklist 3 | 4 | *Basic steps:* 5 | 6 | - Install Java and supporting tools 7 | - install Java JDK 8 | - install Maven 9 | - check Java and Maven work by running a sample test 10 | - Install IntelliJ 11 | - check IntelliJ works by running the sample test 12 | - Install WebDriver Supporting Tools 13 | - download and Install Chrome 14 | - download and Install Firefox 15 | - download and install Marionette GeckoDriver 16 | - download and Install ChromeDriver 17 | - check installs work by running the sample tests 18 | 19 | --- 20 | 21 | ## Install Videos 22 | 23 | *Windows Install Videos* 24 | 25 | * [YouTube Video Showing the Java Install on Windows 10](https://www.youtube.com/watch?v=j-46lYWAHF0) 26 | * https://www.youtube.com/watch?v=j-46lYWAHF0 27 | * [YouTube Video Showing the WebDriver Install on Windows 10](https://www.youtube.com/watch?v=gteqOBS_Ln4) 28 | * https://www.youtube.com/watch?v=gteqOBS_Ln4 29 | 30 | *Mac Install Videos* 31 | 32 | * [YouTube Video Showing the Java Install on a Mac](https://youtu.be/ff5ZsthcSZw) 33 | * https://youtu.be/ff5ZsthcSZw 34 | * [YouTube Video Showing the WebDriver Install on a Mac](https://youtu.be/nq97dfaVmC4) 35 | * https://youtu.be/nq97dfaVmC4 36 | 37 | --- 38 | 39 | # Windows Install Speedrun checklist 40 | 41 | ## Install Java Pre-requisites 42 | 43 | You need to have Java, Maven and IntelliJ installed. 44 | 45 | For instructions on how to install Java, Maven and IntelliJ; and check they are working, use the checklist in `startUsingJavaJunit` project: 46 | 47 | * [`startUsingJavaJunit` project](https://github.com/eviltester/startUsingJavaJUnit) 48 | * [Java Install Checklist](https://github.com/eviltester/startUsingJavaJUnit/blob/master/speedrun_install_java_checklist.md) 49 | 50 | **Note: I currently recommend using `ChromeDriver` as your default driver and the current version of Chrome as your default browser. If you only setup one driver and browser, make it Chrome, it is a lot easier to start with.** 51 | 52 | 53 | --- 54 | 55 | ## Install Firefox GeckoDriver or ChromeDriver the 'fast' way on Windows 56 | 57 | Both GeckoDriver and ChromeDriver are available to install via [Chocolatey](https://chocolatey.org/) 58 | 59 | - ChromeDriver 60 | - https://chocolatey.org/packages/selenium-chrome-driver 61 | - `choco install selenium-chrome-driver` 62 | - Firefox GeckoDriver 63 | - https://chocolatey.org/packages/selenium-gecko-driver 64 | - `choco install selenium-gecko-driver` 65 | 66 | --- 67 | 68 | ## Install Firefox GeckoDriver or ChromeDriver the 'long' way on Windows 69 | 70 | Note: You only really have to install one of these to get started. I recommend ChromeDriver and Chrome. 71 | 72 | --- 73 | 74 | ### Install Chrome and ChromeDriver on Windows 75 | 76 | * `[ ]`Install Current version of Chrome 77 | * `[ ]`download ChromeDriver add it to the path 78 | * https://sites.google.com/a/chromium.org/chromedriver/ 79 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstChromeTest` 80 | * If you did everything correctly then Chrome should have started and a test should have run 81 | 82 | --- 83 | 84 | ### Install Firefox and GeckoDriver on Windows 85 | 86 | * `[ ]` Install Current version of Firefox 87 | * `[ ]`download GeckoDriver add it to the path 88 | * https://github.com/mozilla/geckodriver 89 | * https://github.com/mozilla/geckodriver/releases 90 | * Unzip the downloaded archive file and add to the windows path 91 | - `geckodriver.exe` 92 | * Check that you have added to the path by typing `geckodriver` into a command prompt 93 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstTest` 94 | * If you did everything correctly then Firefox should have started and a test should have run 95 | 96 | --- 97 | 98 | ## Install Sample WebDriver Project on Windows 99 | 100 | * `[ ]`Download Test Project (this has a simple pom.xml and a basic test to run) 101 | * `[ ]`visit https://github.com/eviltester/startUsingSeleniumWebDriver 102 | * `[ ]`download the zip file and unzip somewhere 103 | 104 | * `[ ]`Install and run IntelliJ Community Edition 105 | 106 | * `[ ]`open project for the unzipped pom.xml file 107 | 108 | --- 109 | 110 | * Check the most up to date version of WebDriver 111 | * `[ ]`check for most up to date version of WebDriver in the unzipped pom.xml file 112 | * `[ ]`check the webdriver downloads page or the maven page for the up to date version 113 | - https://www.seleniumhq.org/download/ 114 | * `[ ]`amend the pom.xml file if the version number is not up to date 115 | * `[ ]`exit IntelliJ 116 | 117 | The version number is contained in this section of the `pom.xml` e.g. this says use version `3.13.0` of Selenium WebDriver 118 | 119 | ~~~~~~~~ 120 | 121 | org.seleniumhq.selenium 122 | selenium-java 123 | 3.13.0 124 | 125 | ~~~~~~~~ 126 | 127 | --- 128 | 129 | ## Run Test From IDE on Windows 130 | 131 | * `[ ]`Back in IntelliJ 132 | 133 | * `[ ]`run MyFirstTest, or MyFirstTestFF48 or MyFirstChromeTest class 134 | * `[ ]`right click on the class in the project window and select "Run 135 | 136 | * `[ ]`When the test runs from the IDE, you are finished your install and setup 137 | 138 | --- 139 | 140 | # Mac Install Speedrun checklist - Homebrew 141 | 142 | ## Install Java Pre-requisites 143 | 144 | For instructions on how to install Java, Maven and IntelliJ; and check they are working, use the checklist in `startUsingJavaJunit` project: 145 | 146 | * [`startUsingJavaJunit` project](https://github.com/eviltester/startUsingJavaJUnit) 147 | * [Java Install Checklist](https://github.com/eviltester/startUsingJavaJUnit/blob/master/speedrun_install_java_checklist.md) 148 | 149 | --- 150 | 151 | ## Install WebDriver Sample Project on Mac 152 | 153 | * `[ ]`Install Java JDK, Maven - see [`startUsingJavaJunit` project](https://github.com/eviltester/startUsingJavaJUnit) 154 | * `[ ]`Install IntelliJ Community Edition - see [`startUsingJavaJunit` project](https://github.com/eviltester/startUsingJavaJUnit) 155 | 156 | * `[ ]`Download Test Project (this has a simple pom.xml and a basic test to run) 157 | * `[ ]`visit https://github.com/eviltester/startUsingSeleniumWebDriver 158 | * `[ ]`download the zip file and unzip somewhere 159 | 160 | 161 | **Note: Currently recommend using `ChromeDriver` as your default driver and the current version of Chrome as your default browser. If you only setup one driver and browser, make it Chrome, it is a lot easier to start with.** 162 | 163 | --- 164 | 165 | * `[ ]`open project for the unzipped pom.xml file 166 | 167 | * `[ ]`check most up to date version of webdriver in the unzipped pom.xml file 168 | * `[ ]`check the [Selenium webdriver downloads](https://www.selenium.dev/downloads/) page for the up to date version 169 | * I do not recommend using a beta version 170 | * `[ ]`amend the `pom.xml` file if the version number is not up to date 171 | * `[ ]`exit IntelliJ 172 | 173 | --- 174 | 175 | ## Install SafarDriver on Mac 176 | 177 | SafariDriver is built into the Mac operating system. 178 | 179 | We need to enable remote execution in Safari Browser to use it. 180 | 181 | - `Safari \ Preferences \ Advanced` 182 | - `[x]` show develop menu in menu bar 183 | - `Develop \ Allow Remote Execution` 184 | 185 | --- 186 | 187 | ## Install Firefox and GeckoDriver on Mac 188 | 189 | [Install Homebrew](https://brew.sh/) if you don't already have it. 190 | 191 | * `[ ]` Install Current version of Firefox 192 | * either with cask `brew cask install firefox` 193 | * or visit the site and install 194 | * `[ ]` Install GeckoDriver 195 | - https://brew.sh/ 196 | - https://formulae.brew.sh/formula/geckodriver 197 | * `brew install geckodriver` 198 | 199 | Note: to upgrade use `brew cask upgrade` 200 | 201 | --- 202 | 203 | ## Install Chrome and ChromeDriver on Mac 204 | 205 | * `[ ]`Install Current version of Chrome 206 | * either with cask `brew cask install google-chrome` 207 | * or visit the site and install 208 | * `[ ]` Install ChromeDriver using HomeBrew 209 | * https://brew.sh/ 210 | - https://formulae.brew.sh/cask/chromedriver#default 211 | * `brew cask install chromedriver` 212 | 213 | Note: to upgrade use `brew cask upgrade` 214 | 215 | --- 216 | 217 | ## Install Firefox GeckoDriver or ChromeDriver the 'long' way on Mac 218 | 219 | Remember you can skip this step if you used HomeBrew. 220 | 221 | ### Firefox GeckoDriver the 'long' way on Mac 222 | 223 | * `[ ]`download GeckoDriver add it to the path 224 | * https://github.com/mozilla/geckodriver 225 | * https://github.com/mozilla/geckodriver/releases 226 | * extract into a folder 227 | * if using version 2.53.1 of WebDriver then rename to wires 228 | * if using version 3 of WebDriver then leave as geckodriver 229 | * add path to `.bash_profile` 230 | * `export PATH=$PATH:/folder/you/extracted/it/to` 231 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstTestFF48` 232 | 233 | --- 234 | 235 | ### ChromeDriver the 'long' way on Mac 236 | 237 | * `[ ]` Install ChromeDriver 238 | * `[ ]`download ChromeDriver add it to the path 239 | * https://sites.google.com/a/chromium.org/chromedriver/ 240 | * extract into a folder 241 | * add folder path to `.bash_profile` 242 | * `export PATH=$PATH:/folder/you/extracted/it/to` 243 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstChromeTest` 244 | 245 | --- 246 | 247 | ## Run Test From IDE on Windows or Mac 248 | 249 | * `[ ]` Back in IntelliJ 250 | 251 | * `[ ]` run `MyFirstTest`, or `MyFirstChromeTest` or `MyFirstSafariTest` class depending on which drivers you installed 252 | * `[ ]`right click on the class in the project window and select "Run 253 | 254 | * `[ ]`When the test runs from the IDE, you are finished your install and setup 255 | 256 | > **Note: on mac if you experience an error running ChromeDriver `"chromedriver" cannot be opened because the developer cannot be verified.`** then try the answers here:** https://stackoverflow.com/questions/60362018/ 257 | > 258 | > - I use `which chromedriver` to find out where chromedriver is installed 259 | > - `cd /usr/local/Caskroom/chromedriver/` to go to chromedriver install 260 | > - `ls` to find out the version of chromedriver then 261 | > - `cd 83.0.4103.39` where `82.0.4103.39` was the version shown when I typed `ls` 262 | > - then `xattr -d com.apple.quarantine chromedriver` 263 | > 264 | > Short cut command for this `xattr -d com.apple.quarantine $(which chromedriver)` 265 | 266 | 267 | --- 268 | 269 | 270 | 271 | 272 | Generic Links: 273 | ============== 274 | 275 | 276 | + sample JUnit test project from 277 | * https://github.com/eviltester/startUsingJavaJUnit 278 | * [Java Install Checklist](https://github.com/eviltester/startUsingJavaJUnit/blob/master/speedrun_install_java_checklist.md) 279 | 280 | + Download IntelliJ from 281 | * http://www.jetbrains.com/idea/download/ 282 | 283 | + sample webdriver test project from 284 | * https://github.com/eviltester/startUsingSeleniumWebDriver 285 | 286 | --- 287 | 288 | + Check current webdriver version from 289 | * https://www.selenium.dev/downloads/ 290 | 291 | + ChromeDriver 292 | * https://sites.google.com/a/chromium.org/chromedriver/ 293 | 294 | + Mozilla GeckoDriver 295 | * https://github.com/mozilla/geckodriver 296 | * https://github.com/mozilla/geckodriver/releases 297 | 298 | + Mac HomeBrew and Cask 299 | * https://brew.sh 300 | * https://caskroom.github.io/ 301 | 302 | 303 | --- 304 | 305 | # Selenium Simplified 306 | 307 | ## Online Training and blog teaching Selenium WebDriver with Java 308 | 309 | * www.seleniumsimplified.com 310 | 311 | By Alan Richardson 312 | 313 | * www.eviltester.com 314 | * www.javafortesters.com 315 | * www.compendiumdev.co.uk 316 | * https://uk.linkedin.com/in/eviltester 317 | * [@eviltester](https://twitter.com/eviltester) 318 | 319 | 320 | 321 | --- 322 | 323 | ## Legacy Firefox install instructions 324 | 325 | * `[ ]` If install ESR version of Firefox (45) https://www.mozilla.org/en-US/firefox/organizations/faq/ 326 | * `[ ]`no need to download any extra drivers 327 | * if using WebDriver `2.53.1` 328 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstTest` 329 | * if using WebDriver `3.0.1` (or above) 330 | * `[ ]`in startUsingSeleniumWebDriver folder run command `mvn test -Dtest=MyFirstLegacyFFTest` --------------------------------------------------------------------------------