
1package selenium_testing.locators;2import io.github.bonigarcia.wdm.WebDriverManager;3import org.junit.jupiter.api.*;4import org.openqa.selenium.*;5import org.openqa.selenium.chrome.ChromeDriver;6import org.openqa.selenium.support.ByIdOrName;7import org.openqa.selenium.support.Color;8import org.openqa.selenium.support.Colors;9import org.openqa.selenium.support.events.AbstractWebDriverEventListener;10import org.openqa.selenium.support.events.EventFiringWebDriver;11import org.openqa.selenium.support.pagefactory.ByAll;12import org.openqa.selenium.support.pagefactory.ByChained;13import org.openqa.selenium.support.ui.*;14import java.util.List;15public class LocatorExamplesTests {16    private WebDriver driver;17    @BeforeEach18    public void createDriver() {19        WebDriverManager.chromedriver().setup();20        driver = new ChromeDriver();21        driver.get("https://eviltester.github.io/supportclasses/");22    }23    // The select class makes it easy to work with Select options24    // rather than finding the select menu and then all the options25    // below it - this is the only Element Abstraction in the26    // support classes27    @Test28    public void canSelectAnOptionUsingSelect(){29        final WebElement selectMenu = driver.findElement(By.id("select-menu"));30        final Select select = new Select(selectMenu);31        select.selectByVisibleText("Option 3");32        Assertions.assertEquals("3",33                select.getFirstSelectedOption().34                        getAttribute("value"));35    }36    @Test37    public void findInstructionsByIdOrName(){38        // findElement returns the element with the id if it exists, and if not searches for it via the name39        final WebElement instructionsPara = driver.findElement(40                new ByIdOrName("instruction-text"));41        final List<WebElement> instructionsParaAgain = driver.findElements(42                new ByIdOrName("instructions"));43        Assertions.assertEquals(instructionsPara.getText(),44                instructionsParaAgain.get(0).getText());45    }46    @Test47    public void quotesEscapingToCreateXPath(){48        Assertions.assertEquals("\"literal\"",49                Quotes.escape("literal"));50        Assertions.assertEquals("\"'single-quoted'\"",51                Quotes.escape("'single-quoted'"));52        Assertions.assertEquals("'\"double-quoted\"'",53                Quotes.escape("\"double-quoted\""));54        Assertions.assertEquals("concat(\"\", '\"', \"quot'end\", '\"')",55                Quotes.escape("\"quot'end\""));56        Assertions.assertEquals("concat(\"'quo\", '\"', \"ted'\")",57                Quotes.escape("'quo\"ted'"));58    }59    @Test60    public void checkColors(){61        final WebElement title = driver.findElement(By.id("instruction-title"));62        // Colors is an enum of named Color objects63        final Color blackValue = Colors.BLACK.getColorValue();64        // Color has methods to help convert between RBG, HEX65        Assertions.assertEquals("#000000",blackValue.asHex());66        Assertions.assertEquals("rgba(0, 0, 0, 1)",blackValue.asRgba());67        Assertions.assertEquals("rgb(0, 0, 0)",blackValue.asRgb());68        // color values returned by WebElement's getCSSValue are always69        // RGBA format, not the HTML source HEX or RGB70        Assertions.assertEquals(title.getCssValue("background-color"),71                blackValue.asRgba());72        // can create custom colors using the RGB input constructor73        // if the Colors enum does not have what we need74        final Color redValue = new Color(255,0,0, 1);75        Assertions.assertEquals(title.getCssValue("color"), redValue.asRgba());76    }77    @Test78    public void waitForMessage() {79        final WebElement selectMenu = driver.findElement(By.id("select-menu"));80        final Select select = new Select(selectMenu);81        select.selectByVisibleText("Option 2");82        // We are so used to using WebDriverWait and the ExpectedConditions class83        // that we might not have realised these are part of the support packages84        new WebDriverWait(driver, 10).until(85                ExpectedConditions.textToBe(By.id("message"), "Received message: selected 2"));86    }87    @Test88    public void canGetInfoAboutSelect(){89        final WebElement selectMenu = driver.findElement(By.id("select-menu"));90        final Select select = new Select(selectMenu);91        // the isMultiple method should be false for the select-menu item92        final WebElement multiSelectMenu = driver.findElement(By.id("select-multi"));93        final Select multiSelect = new Select(multiSelectMenu);94        // the isMultiple method should be true for multi select95        Assertions.assertFalse(select.isMultiple());96        Assertions.assertTrue(multiSelect.isMultiple());97    }98    @Test99    public void canGetAllOptionsFromSelect(){100        final WebElement selectMenu = driver.findElement(By.id("select-menu"));101        final Select select = new Select(selectMenu);102        // getOptions will return a List of WebElement103        // and allow me to access the options using104        // simple List methods105        List<WebElement> options = select.getOptions();106        Assertions.assertEquals(4,options.size());107        Assertions.assertEquals("Option 1", options.get(0).getText());108    }109    @Test110    public void canSelectSingleOptions(){111        // demo test to show single-select capabilities112        final WebElement selectMenu = driver.findElement(By.id("select-menu"));113        final Select select = new Select(selectMenu);114        // select will do nothing because this option is selected by default115        select.selectByIndex(0);116        Assertions.assertEquals("Option 1", select.getFirstSelectedOption().getText());117        // I can select the second item by Index 1 to chooose Option 2118        select.selectByIndex(1);119        Assertions.assertEquals("Option 2", select.getFirstSelectedOption().getText());120        // I can select the first by using the value "1"121        select.selectByValue("1");122        Assertions.assertEquals("Option 1", select.getFirstSelectedOption().getText());123        // and I can select using the text in the option124        select.selectByVisibleText("Option 3");125        Assertions.assertEquals("3", select.getFirstSelectedOption().getAttribute("value"));126    }127    @Test128    public void canSelectAndDeselectMultiOptions(){129        // demo test to show multi-select capabilities130        final WebElement selectMenu = driver.findElement(By.id("select-multi"));131        final Select select = new Select(selectMenu);132        // make sure nothing is selected with deselectAll133        select.deselectAll();134        // A normal select by index to get the First item135        select.selectByIndex(0);136        Assertions.assertEquals("First", select.getFirstSelectedOption().getText());137        // if I select I can deselect - by index, text or value138        select.deselectByIndex(0);139        // when nothing is selected a NoSuchElementException is thrown140        Assertions.assertThrows(NoSuchElementException.class, () -> {141            select.getFirstSelectedOption(); });142        // select two items - values 20 and 30143        select.selectByValue("20");144        select.selectByValue("30");145        // use getAllSelectedOptions, there should be 2 in the list146        final List<WebElement> selected = select.getAllSelectedOptions();147        Assertions.assertEquals(2, selected.size());148        // assert on the getText for the list entries149        Assertions.assertEquals("Second", selected.get(0).getText());150        Assertions.assertEquals("Third", selected.get(1).getText());151        // deselect the first one - assert visible text "Second"152        select.deselectByVisibleText("Second");153        // and assert that the first selected option text is "Third"154        Assertions.assertEquals("Third", select.getFirstSelectedOption().getText());155        // deselect them all to finish156        select.deselectAll();157        Assertions.assertEquals(0, select.getAllSelectedOptions().size());158        Assertions.assertEquals(selectMenu, select.getWrappedElement());159    }160    //@Disabled("To be enabled if run independently")161    @Test162    public void canClickAButton(){163        final WebElement buttonElement = driver.findElement(By.id("resend-select"));164        Button button = new Button(buttonElement);165        // rather than click on a button element,166        // could we click on a Button?167        Assertions.assertEquals("Resend Single Option Message",168                button.getText());169        button.click();170        new WebDriverWait(driver, 10).171                until(ExpectedConditions.textToBe(By.id("message"),172                        "Received message: selected 1"));173    }174    @Test175    public void byIdOrName(){176        WebElement idButton = driver.findElement(By.id("resend-select"));177        Assertions.assertEquals("Resend Single Option Message",178                idButton.getText());179        WebElement namedButton = driver.findElement(By.name("resend-select"));180        Assertions.assertEquals("Resend Multi Option Message",181                namedButton.getText());182        // ByIdOrName can match by id, and if that doesn't match treat it as a name183        // use ByIdOrName to find a button element "resend-select"184        // and the assertions should pass185        WebElement button = driver.findElement(new ByIdOrName("resend-select"));186        Assertions.assertEquals(idButton, button);187        Assertions.assertNotEquals(namedButton, button);188        //ByIdOrName findElements returns all id and name matches189        //findElements for "resend-select" should find 2 buttons190        List<WebElement> buttons = driver.findElements(new ByIdOrName("resend-select"));191        Assertions.assertEquals(2, buttons.size());192        // the elements identified should be the same as we found initially193        Assertions.assertTrue(buttons.contains(idButton));194        Assertions.assertTrue(buttons.contains(namedButton));195    }196    @Test197    public void byAll(){198        // we could use ByAll to find by id or by name199        // by all is a collator, so given a number of locators, find all items that match200        final List<WebElement> buttons = driver.findElements(201                new ByAll(By.id("resend-select"),202                        By.name("resend-select")));203        Assertions.assertEquals(2, buttons.size());204        Assertions.assertTrue(buttons.contains(driver.findElement(By.id("resend-select"))));205        Assertions.assertTrue(buttons.contains(driver.findElement(By.name("resend-select"))));206    }207    @Test208    public void byChained(){209        final WebElement resendSingle = driver.findElement(By.id("resend-select"));210        resendSingle.click();211        resendSingle.click();212        resendSingle.click();213        resendSingle.click();214        final WebElement resend = driver.findElement(By.id("resend-multi"));215        resend.click();216        resend.click();217        // TODO: make this more specific to only find messages under a 'list'218        final List<WebElement> allMessages = driver.findElements(219                new ByChained(By.name("list"),220                        By.className("message")));221        Assertions.assertEquals(6, allMessages.size());222        // then just the #single list .message223        final List<WebElement> singleMessages = driver.findElements(224                new ByChained(By.id("single"),By.name("list"),225                        By.className("message")));226        Assertions.assertEquals(4, singleMessages.size());227        // then the #multi list .message228        final List<WebElement> multiMessages = driver.findElements(229                new ByChained(By.id("multi"),By.name("list"),230                        By.className("message")));231        Assertions.assertEquals(2, multiMessages.size());232    }233    @Test234    public void loggingFindingElements() {235        final By resend = By.id("resend-select");236        final By noSuchElement = By.id("no-such-element");237        EventFiringWebDriver events = new EventFiringWebDriver(driver);238        events.register(new LocalEventFiringListener());239        WebElement resendElem = events.findElement(resend);240        Assertions.assertNotNull(resendElem);241        Assertions.assertThrows(NoSuchElementException.class, () -> {242            events.findElement(noSuchElement);243        });244    }245    private class LocalEventFiringListener extends AbstractWebDriverEventListener {246        @Override247        public void beforeFindBy(By by, WebElement element, WebDriver driver) {248            System.out.println("Looking For " + by.toString());249        }250        @Override251        public void afterFindBy(By by, WebElement element, WebDriver driver) {252            System.out.println("Finished looking for " + by.toString());253        }254    }255    @AfterEach256    public void closeDriver() { driver.quit(); }257    private class Button implements WrapsElement {258        private final WebElement button;259        public Button(WebElement buttonElement) {260            this.button = buttonElement;261        }262        @Override263        public WebElement getWrappedElement() {264            return button;265        }266        public String getText() {267            return button.getText();268        }269        public void click() {270            button.click();271        }272    }273}...
