From bbc1e6f2fc5682e39cdabf7dd8080cbcf0afdcff Mon Sep 17 00:00:00 2001 From: James Tacker Date: Fri, 5 Apr 2019 09:37:38 -0700 Subject: [PATCH 1/2] updated FullJourneyTest --- src/test/java/exercises/FullJourneyTest.java | 78 ++++++++++---------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/test/java/exercises/FullJourneyTest.java b/src/test/java/exercises/FullJourneyTest.java index 707d926..dd8d20d 100644 --- a/src/test/java/exercises/FullJourneyTest.java +++ b/src/test/java/exercises/FullJourneyTest.java @@ -19,24 +19,25 @@ public class FullJourneyTest { public void fullCustomerJourney(Method method) throws MalformedURLException { // Input your SauceLabs Credentials - String sauceUserName = "SAUCE_USERNAME"; - String sauceAccessKey = "SAUCE_ACCESS_KEY"; + String sauceUsername = System.getenv("SAUCE_USERNAME"); + String sauceAccessKey = System.getenv("SAUCE_ACCESS_KEY"); MutableCapabilities capabilities = new MutableCapabilities(); - //sets browser to Safari - capabilities.setCapability("browserName", "Safari"); + //sets browser to Firefox + capabilities.setCapability("browserName", "firefox"); //sets operating system to macOS version 10.13 capabilities.setCapability("platform", "macOS 10.13"); //sets the browser version to 11.1 - capabilities.setCapability("version", "11.1"); + capabilities.setCapability("version", "58.0"); //sets your test case name so that it shows up in Sauce Labs capabilities.setCapability("name", method.getName()); - capabilities.setCapability("username", sauceUserName); + //sets your Sauce Labs Credentials + capabilities.setCapability("username", sauceUsername); capabilities.setCapability("accessKey", sauceAccessKey); //instantiates a remote WebDriver object with your desired capabilities @@ -58,91 +59,92 @@ public void fullCustomerJourney(Method method) throws MalformedURLException { String userField = "[data-test='username']"; String passField = "[data-test='password']"; String loginBtn = "[value='LOGIN']"; - String backpack = "div:nth-child(1) > div.pricebar > button"; - String jacket = "div:nth-child(4) > div.pricebar > button"; - String cart = "#shopping_cart_container"; - String rmvBtn = "div:nth-child(4) > div.cart_item_label > div.item_pricebar > button"; - String continueShopping = "a.cart_cancel_link"; - String checkoutLink = "a.cart_checkout_link"; + String backpack = "#inventory_container > div > div:nth-child(1) > div.pricebar > button"; + String cart = "#shopping_cart_container > a > svg"; + String rmvBtn = "#cart_contents_container > div > div.cart_list > div.cart_item > div.cart_item_label > div.item_pricebar > button"; + String continueShopping = "div.cart_footer > a.btn_secondary"; + String checkoutLink = "div.cart_footer > a.btn_action.checkout_button"; String firstNameField = "[data-test='firstName']"; String lastNameField = "[data-test='lastName']"; String postalField= "[data-test='postalCode']"; - String cartCheckout = "[value='CONTINUE']"; - String finished = "a.cart_checkout_link"; - String inventoryPage = "https://www.saucedemo.com/inventory.html"; - String cartPage = "https://www.saucedemo.com/cart.html"; - String checkout1 = "https://www.saucedemo.com/checkout-step-one.html"; - String checkout2 = "https://www.saucedemo.com/checkout-step-two.html"; + String continueLink = "div.checkout_buttons > input"; + String finished = "div.cart_footer > a.btn_action.cart_button"; String complete = "https://www.saucedemo.com/checkout-complete.html"; // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS) ; + driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + // send username keystrokes driver.findElement(By.cssSelector(userField)).sendKeys(username); + System.out.println("sending username"); // send password keystrokes driver.findElement(By.cssSelector(passField)).sendKeys(password); + System.out.println("sending password"); + // click login button to submit keystrokes driver.findElement(By.cssSelector(loginBtn)).click(); - - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS) ; + System.out.println("clicking 'Submit' button"); // add items to the cart driver.findElement(By.cssSelector(backpack)).click(); - driver.findElement(By.cssSelector(jacket)).click(); + System.out.println("adding backpack"); // proceed to checkout driver.findElement(By.cssSelector(cart)).click(); - - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS) ; + System.out.println("clicking cart icon"); // remove item from cart driver.findElement(By.cssSelector(rmvBtn)).click(); + System.out.println("removing item from cart"); // continue shopping driver.findElement(By.cssSelector(continueShopping)).click(); - - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS) ; + System.out.println("clicking 'Continue Shopping' button"); // re-add item to cart and proceed to checkout - driver.findElement(By.cssSelector(jacket)).click(); - driver.findElement(By.cssSelector(cart)).click(); + driver.findElement(By.cssSelector(backpack)).click(); + System.out.println("re-adding backpack back to cart"); // wait 5 seconds driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + driver.findElement(By.cssSelector(cart)).click(); + System.out.println("clicking cart icon"); + + //Click Checkout Link driver.findElement(By.cssSelector(checkoutLink)).click(); + System.out.println("clicking the 'Checkout' button"); // wait 5 seconds driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); // proceed to shipping info (checkout step 1) driver.findElement(By.cssSelector(firstNameField)).sendKeys(firstname); + System.out.println("adding first name in shipping info"); + driver.findElement(By.cssSelector(lastNameField)).sendKeys(lastname); - driver.findElement(By.cssSelector(postalField)).sendKeys(postal); + System.out.println("adding last name in shipping info"); - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + driver.findElement(By.cssSelector(postalField)).sendKeys(postal); + System.out.println("adding zip code in shipping info"); //Click Cart Checkout Link - driver.findElement(By.cssSelector(cartCheckout)).click(); - - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); + driver.findElement(By.cssSelector(continueLink)).click(); + System.out.println("clicking the 'Continue' button "); // proceed to confirmation page (checkout step 2) driver.findElement(By.cssSelector(finished)).click(); + System.out.println("clicking the 'Finished' button"); // wait 5 seconds driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); // assert that the test is finished by checking the last page's URL Assert.assertEquals(driver.getCurrentUrl(), complete); + System.out.println("asserting last page's url = 'https://www.saucedemo.com/checkout-complete.html'" ); // Then quit the driver session driver.quit(); From 64356422d12e709192be85a80364e7cd60d25ce5 Mon Sep 17 00:00:00 2001 From: James Tacker Date: Fri, 5 Apr 2019 11:25:14 -0700 Subject: [PATCH 2/2] updated exercise guides --- exercise-guides/exercise1.md | 106 ++----------------- exercise-guides/exercise4.md | 55 +++++++--- exercise-guides/exercise6.md | 6 -- exercise-guides/getting-started.md | 2 +- src/test/java/exercises/FullJourneyTest.java | 6 +- 5 files changed, 55 insertions(+), 120 deletions(-) diff --git a/exercise-guides/exercise1.md b/exercise-guides/exercise1.md index 5e22077..802c8c6 100644 --- a/exercise-guides/exercise1.md +++ b/exercise-guides/exercise1.md @@ -78,119 +78,33 @@ ## Part Three: Abstract Test Details: 1. In `src/test/java/exercises/` create a new class called `LoginFeatureTest`. -2. Create a new class method with the following: +2. Create a new `@Test` class method called `ShouldBeAbleToLogin`: ``` public class LoginFeatureTest { protected WebDriver driver; + @Test - public void ShouldBeAbleToLogin(Method method) - throws MalformedURLException - { + public void ShouldBeAbleToLogin(Method method) { } } ``` -3. In `FullJourneyTest`, copy everything from: - - `Line 21` - ``` - // Input your SauceLabs Credentials - ``` - to `Line 87`: - ``` - driver.findElement(By.cssSelector(loginBtn)).click(); - ``` - and paste it into the `LoginFeatureTest` class method: `ShouldBeAbleToLogin` -4. Delete unecessary element locators such as: - ``` - String backpack = "div:nth-child(1) > div.pricebar > button"; - String jacket = "div:nth-child(4) > div.pricebar > button"; - String cart = "#shopping_cart_container"; - String rmvBtn = "div:nth-child(4) > div.cart_item_label > div.item_pricebar > button"; - String continueShopping = "a.cart_cancel_link"; - ... - ``` -5. Add this `Assertion` at the end of the test: +3. In `FullJourneyTest`, copy everything related to the login feature + and paste it into the `LoginFeatureTest` class method: `ShouldBeAbleToLogin`. +4. Add this `Assertion` at the end of the `ShouldBeAbleToLogin`: ``` Assert.assertEquals("https://www.saucedemo.com/inventory.html", driver.getCurrentUrl()); ``` -6. Run the test: +5. Run the test: ``` mvn test -Dtest=LoginFeatureTest ``` -7. Next we need to create an **`@AfterMethod` to send the test results to Sauce Labs and add a `@BeforeMethod` that takes care of the driver instantiation before we run our test: - * ``` - @AfterMethod - public void teardown(ITestResult result) { - ((JavascriptExecutor)driver).executeScript( - "sauce:job-result=" + (result.isSuccess() ? "passed" : "failed")); - driver.quit(); - } - ``` - * ``` - @BeforeMethod - public void setUp(Method method) throws MalformedURLException - { - // Input your SauceLabs Credentials - String sauceUsername = System.getenv("SAUCE_USERNAME"); - String sauceAccessKey = System.getenv("SAUCE_ACCESS_KEY"); - - MutableCapabilities capabilities = new MutableCapabilities(); - - //sets browser to Safari - capabilities.setCapability("browserName", "Safari"); - - //sets operating system to macOS version 10.13 - capabilities.setCapability("platform", "macOS 10.13"); - - //sets the browser version to 11.1 - capabilities.setCapability("version", "11.1"); - - //sets your test case name so that it shows up in Sauce Labs - capabilities.setCapability("name", method.getName()); - capabilities.setCapability("username", sauceUsername); - capabilities.setCapability("accessKey", sauceAccessKey); - - //instantiates a remote WebDriver object with your desired capabilities - driver = new RemoteWebDriver(new URL("https://ondemand.saucelabs.com/wd/hub"), capabilities); - } - ``` - Your test class should now look like this: - ``` - @Test - public void ShouldBeAbleToLogin() { - - //navigate to the url of the Sauce Labs Sample app - driver.navigate().to("https://www.saucedemo.com"); - - // Ignore the following selectors - String username = "standard_user"; - String password = "secret_sauce"; - String userField = "[data-test='username']"; - String passField = "[data-test='password']"; - String loginBtn = "[value='LOGIN']"; - - // wait 5 seconds - driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); - - // send username keystrokes - driver.findElement(By.cssSelector(userField)).sendKeys(username); - - // send password keystrokes - driver.findElement(By.cssSelector(passField)).sendKeys(password); - - // click login button to submit keystrokes - driver.findElement(By.cssSelector(loginBtn)).click(); - - // assert that the next page opened - Assert.assertEquals("https://www.saucedemo.com/inventory.html", driver.getCurrentUrl()); - } - ``` -8. Run the final test of this exercise: +6. Create a **`@BeforeMethod`** that takes care of `WebDriver` instantiation and setting `capabilities` before we run our test, and add an **`@AfterMethod`** to send the test results to Sauce Labs +7. Run the final test of this exercise: ``` mvn test -Dtest=LoginFeatureTest ``` -9. Use `git stash` or `git commit` to discard or save your changes. Checkout the next branch to proceed to the next exercise +8. Use `git stash` or `git commit` to discard or save your changes. Checkout the next branch to proceed to the next exercise ``` git checkout 02_page_objects ``` \ No newline at end of file diff --git a/exercise-guides/exercise4.md b/exercise-guides/exercise4.md index bb11de2..6927b1e 100644 --- a/exercise-guides/exercise4.md +++ b/exercise-guides/exercise4.md @@ -1,9 +1,31 @@ # Exercise 4: Configure Atomic Tests -## Part One: Modify `ConfirmationPage` +## Part One: Create `CheckoutCompletePage` 1. Checkout the branch `04_configure_atomic_tests`. -2. Open `ConfirmationPage` in `src > test > java > pages`. -3. Add the following class methods: +2. In `src > test > java > pages`, create a new class called `CheckoutCompletePage` +3. Add the following: + ``` + public class CheckoutCompletePage { + private final WebDriver driver; + + public CheckoutCompletePage(WebDriver driver) { + this.driver = driver; + } + } + ``` +4. Add a new class method called `IsLoaded()` to confirm the correct checkout page is loaded: + ``` + public boolean IsLoaded() + { + return driver.getCurrentUrl().contains("https://www.saucedemo.com/checkout-complete.html"); + } + ``` + +
+ +## Part Two: Modify `ConfirmationPage` +1. Open `ConfirmationPage` in `src > test > java > pages`. +2. Add the following class methods: ``` public void visit() { driver.get("https://www.saucedemo.com/checkout-step-two.html"); @@ -16,14 +38,15 @@ } ``` ``` - public CheckoutCompletePage finishCheckout() { - String checkoutLink = "cart_checkout_link"; - driver.findElement(By.className(checkoutLink)).click(); - return new CheckoutCompletePage; + public CheckoutCompletePage FinishCheckout() + { + String finished =".btn_action.cart_button"; + driver.findElement(By.cssSelector(finished)).click(); + return new CheckoutCompletePage(driver); } ``` -4. Open **`CheckoutFeatureTest`** located in `src > test > java > exercises`. -5. You'll notice that the **`ShouldBeAbleToCheckout()`** class method steps through many pages to get to the checkout function. The existing test flow works like this: +3. Open **`CheckoutFeatureTest`** located in `src > test > java > exercises`. +4. You'll notice that the **`ShouldBeAbleToCheckout()`** class method steps through many pages to get to the checkout function. The existing test flow works like this: * User logs in * Adds some items to the cart * Clicks the cart icon to proceed to checkout @@ -32,14 +55,14 @@ This approach is under-optimized because our tests shouldn't rely on the asserti
-## Part Two: Implement the `JavascriptExecutor` to Bypass Pages +## Part Three: Implement the `JavascriptExecutor` to Bypass Pages 1. Go back to **`ConfirmationPage`** and add the following class method: ``` - public void setCartState() { + public void setPageState() { driver.navigate().refresh(); } ``` -2. In **`setCartState()`** add the following **`JavaScriptExecutor`** command to bypass logging in through the **`LoginPage`** object: +2. In **`setPageState()`** add the following **`JavaScriptExecutor`** command to bypass logging in through the **`LoginPage`** object: ``` ((JavascriptExecutor)driver).executeScript("window.sessionStorage.setItem('standard-username', 'standard-user')"); ``` @@ -53,11 +76,15 @@ This approach is under-optimized because our tests shouldn't rely on the asserti public void ShouldBeAbleToCheckoutWithItems() { // wait 5 seconds driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS) ; + ConfirmationPage confirmationPage = new ConfirmationPage(driver); confirmationPage.visit(); - confirmationPage.setCartState(); - confirmationPage.checkout(); + confirmationPage.setPageState(); Assert.assertTrue(confirmationPage.hasItems()); + + CheckoutCompletePage completePage = confirmationPage.FinishCheckout(); + // assert that the test is finished by checking the last page's URL + Assert.assertTrue(completePage.IsLoaded()); } ``` 5. Save all and run the following command to ensure the build passes: diff --git a/exercise-guides/exercise6.md b/exercise-guides/exercise6.md index 5193c7c..c6bd110 100644 --- a/exercise-guides/exercise6.md +++ b/exercise-guides/exercise6.md @@ -5,9 +5,6 @@ 2. Open up the `pom.xml` and modify the following `plugin` setting: * Before: ``` - org.apache.maven.plugins - maven-surefire-plugin - 2.22.1 classes 1 @@ -16,9 +13,6 @@ ``` * After: ``` - org.apache.maven.plugins - maven-surefire-plugin - 2.22.1 methods 10 diff --git a/exercise-guides/getting-started.md b/exercise-guides/getting-started.md index bfa4ba3..dedd7d8 100644 --- a/exercise-guides/getting-started.md +++ b/exercise-guides/getting-started.md @@ -9,7 +9,7 @@ Before you begin, consult the parent [README](../README.md#getting-started-with- * [Setup Selenium Project](../README.md#setup-the-project) -Download the latest [release](https://github.com/saucelabs-training/Getting-Started-with-Selenium/releases) archive and import the project into your local environment and begin experimenting with creating your own automated Selenium tests! +Download the latest [release](https://github.com/saucelabs-training/saucecon19-best-practices-workshop/releases) (`saucecon-bestpractices-workshop-.zip`) archive and import the project into your local environment and begin experimenting with creating your own automated Selenium tests! ## Exercise List 1. [Automate Tests on SauceLabs](exercise1.md) diff --git a/src/test/java/exercises/FullJourneyTest.java b/src/test/java/exercises/FullJourneyTest.java index dd8d20d..6743d70 100644 --- a/src/test/java/exercises/FullJourneyTest.java +++ b/src/test/java/exercises/FullJourneyTest.java @@ -31,7 +31,7 @@ public void fullCustomerJourney(Method method) throws MalformedURLException { capabilities.setCapability("platform", "macOS 10.13"); //sets the browser version to 11.1 - capabilities.setCapability("version", "58.0"); + capabilities.setCapability("version", "latest"); //sets your test case name so that it shows up in Sauce Labs capabilities.setCapability("name", method.getName()); @@ -42,11 +42,11 @@ public void fullCustomerJourney(Method method) throws MalformedURLException { //instantiates a remote WebDriver object with your desired capabilities driver = new RemoteWebDriver(new URL("https://ondemand.saucelabs.com/wd/hub"), capabilities); + System.out.println("creating remote WebDriver and setting capabilities"); //navigate to the url of the Sauce Labs Sample app driver.navigate().to("https://www.saucedemo.com"); - // navigate to desired page - driver.get("https://www.saucedemo.com"); + System.out.println("navigating to web application"); // Specify Data String firstname = "john";