├── .gitignore ├── LICENSE ├── README.md ├── build.sh ├── circle.yml ├── docs ├── Introducing BDD.pptx ├── Measuring TDD.pptx └── What's New in Java 8.pptx ├── pom.xml ├── src ├── main │ ├── java │ │ └── com │ │ │ ├── algocrafts │ │ │ ├── algorithm │ │ │ │ ├── Attemptable.java │ │ │ │ ├── Duration.java │ │ │ │ ├── PropertyDefinition.java │ │ │ │ ├── Retry.java │ │ │ │ ├── Retryable.java │ │ │ │ └── SortedCounter.java │ │ │ ├── browsers │ │ │ │ ├── Browsers.java │ │ │ │ ├── ChromeDriverSupplier.java │ │ │ │ ├── FirefoxDriverSupplier.java │ │ │ │ ├── FirefoxDriverSupplierOnWindows.java │ │ │ │ ├── HeadlessFirefoxDriverSupplierOnLinux.java │ │ │ │ ├── HeadlessFirefoxDriverSupplierOnMacOs.java │ │ │ │ ├── InternetExplorerDriverSupplier.java │ │ │ │ └── SafariDriverSupplier.java │ │ │ ├── clickables │ │ │ │ ├── Button.java │ │ │ │ ├── Clickables.java │ │ │ │ ├── ImageButton.java │ │ │ │ ├── Link.java │ │ │ │ ├── Menu.java │ │ │ │ └── Url.java │ │ │ ├── conditions │ │ │ │ ├── ElementPredicates.java │ │ │ │ ├── Equals.java │ │ │ │ ├── HasElements.java │ │ │ │ ├── OptionalPresents.java │ │ │ │ ├── PagePredicates.java │ │ │ │ ├── StringContains.java │ │ │ │ └── StringEquals.java │ │ │ ├── converters │ │ │ │ ├── ElementAtIndex.java │ │ │ │ ├── ElementFunctions.java │ │ │ │ ├── Filter.java │ │ │ │ ├── FirstItem.java │ │ │ │ ├── FirstMatch.java │ │ │ │ ├── FrameLocator.java │ │ │ │ ├── GetText.java │ │ │ │ ├── OptionalGetter.java │ │ │ │ ├── Ordinal.java │ │ │ │ ├── StreamToList.java │ │ │ │ ├── StringConverter.java │ │ │ │ ├── StringToInt.java │ │ │ │ └── StringToMonth.java │ │ │ ├── datepicker │ │ │ │ ├── CalendarPicker.java │ │ │ │ ├── Datepicker.java │ │ │ │ └── DayPicker.java │ │ │ ├── domain │ │ │ │ ├── Countries.java │ │ │ │ ├── CreditCardType.java │ │ │ │ ├── SetDiff.java │ │ │ │ └── UnitedStates.java │ │ │ ├── forms │ │ │ │ ├── Checkbox.java │ │ │ │ ├── FileInput.java │ │ │ │ ├── FormControl.java │ │ │ │ ├── ForwardingSelect.java │ │ │ │ ├── Input.java │ │ │ │ └── RadioButton.java │ │ │ ├── locators │ │ │ │ ├── ElementLocator.java │ │ │ │ ├── ElementsLocator.java │ │ │ │ ├── Locators.java │ │ │ │ ├── OptionalElementLocator.java │ │ │ │ └── SelectLocator.java │ │ │ ├── objectcache │ │ │ │ ├── OneKeyCachePolicy.java │ │ │ │ ├── OneKeyLFUPolicy.java │ │ │ │ ├── OneKeyLRUPolicy.java │ │ │ │ └── SelfPopulatingCache.java │ │ │ ├── pages │ │ │ │ └── Page.java │ │ │ ├── selectors │ │ │ │ ├── ClassName.java │ │ │ │ ├── CssSelector.java │ │ │ │ ├── Id.java │ │ │ │ ├── LinkText.java │ │ │ │ ├── Name.java │ │ │ │ ├── PartialLinkText.java │ │ │ │ ├── TagName.java │ │ │ │ └── Xpath.java │ │ │ ├── selenium │ │ │ │ ├── Actionable.java │ │ │ │ ├── Browser.java │ │ │ │ ├── CachedWebDriverSupplier.java │ │ │ │ ├── Clickable.java │ │ │ │ ├── Element.java │ │ │ │ ├── ElementFinder.java │ │ │ │ ├── ElementsFinder.java │ │ │ │ ├── ExplicitWait.java │ │ │ │ ├── Locating.java │ │ │ │ ├── Locator.java │ │ │ │ └── SearchScope.java │ │ │ └── table │ │ │ │ ├── Table.java │ │ │ │ └── TableContents.java │ │ │ ├── bookstore │ │ │ ├── BillingAddressForm.java │ │ │ ├── BookPage.java │ │ │ ├── BookStoreId.java │ │ │ ├── BookstoreHomePage.java │ │ │ ├── CreditCardForm.java │ │ │ ├── OtherInformationForm.java │ │ │ ├── ShippingAddressForm.java │ │ │ ├── ShoppingCartPage.java │ │ │ └── domain │ │ │ │ ├── Address.java │ │ │ │ ├── CreditCard.java │ │ │ │ ├── ErrorMessages.java │ │ │ │ ├── MailingOptions.java │ │ │ │ └── OtherInformation.java │ │ │ ├── daugherty │ │ │ ├── AllMenuLocatorForDaugherty.java │ │ │ ├── DaughertyHomePage.java │ │ │ └── MenuGroupLocator.java │ │ │ ├── extjs │ │ │ ├── CalendarClicker.java │ │ │ ├── CalendarIntegerLocator.java │ │ │ └── TriggerHover.java │ │ │ ├── google │ │ │ └── GooglePage.java │ │ │ ├── jquery │ │ │ ├── JQueryHomePage.java │ │ │ ├── datepicker │ │ │ │ ├── JQueryDatePickerPage.java │ │ │ │ └── locators │ │ │ │ │ ├── CalendarClicker.java │ │ │ │ │ ├── CalendarIntegerLocator.java │ │ │ │ │ └── JQueryDayPicker.java │ │ │ └── menu │ │ │ │ ├── AllMenuLocatorForJQuery.java │ │ │ │ ├── MenuGroupLocator.java │ │ │ │ └── MouseOverMenuLocator.java │ │ │ ├── orgsync │ │ │ ├── AllMenuLocatorForOrgSync.java │ │ │ ├── MenuGroupLocator.java │ │ │ ├── MouseOverLocator.java │ │ │ └── OrgSyncHomePage.java │ │ │ └── ticketfly │ │ │ ├── TicketflyEventPage.java │ │ │ └── TicketflyPage.java │ └── resources │ │ ├── bookstore │ │ ├── beans │ │ │ ├── context.xml │ │ │ ├── domain.xml │ │ │ ├── pages.xml │ │ │ └── properties.xml │ │ └── properties │ │ │ └── page.properties │ │ ├── context │ │ ├── context.xml │ │ ├── pages.xml │ │ └── properties.xml │ │ ├── html │ │ └── radio.html │ │ ├── log4j.properties │ │ ├── logback.xml │ │ └── properties │ │ └── page.properties └── test │ ├── java │ ├── com │ │ └── algocrafts │ │ │ ├── BookStoreShoppingTest.java │ │ │ ├── DragAndDropTest.java │ │ │ ├── GoogleAutoCompleteTest.java │ │ │ ├── OrgSyncHomePageTest.java │ │ │ ├── SpringUploadTest.java │ │ │ ├── TableTest.java │ │ │ ├── UploadTest.java │ │ │ ├── chapter1 │ │ │ ├── BrowserTest.java │ │ │ └── LinkClickingTest.java │ │ │ ├── chapter13 │ │ │ ├── BetterJQueryDatepicker.java │ │ │ ├── JQueryDatePickerMultipleBrowserTest.java │ │ │ ├── JQueryDatePickerTest.java │ │ │ ├── MuchBetterJQueryDatepicker.java │ │ │ ├── NaiveDatepicker.java │ │ │ └── NaiveJQueryDatepickerTest.java │ │ │ ├── chapter2 │ │ │ ├── AlertTest.java │ │ │ ├── BrowserTest.java │ │ │ ├── ConfirmTest.java │ │ │ ├── CookieTest.java │ │ │ ├── ImeHandlerTest.java │ │ │ ├── LogsTest.java │ │ │ ├── NavigationTest.java │ │ │ ├── TargetLocatorTest.java │ │ │ ├── TimeoutsTest.java │ │ │ ├── WebDriverTest.java │ │ │ ├── WindowsTest.java │ │ │ └── factory │ │ │ │ ├── BetterWebDriverFactory.java │ │ │ │ ├── Browser.java │ │ │ │ ├── ChromeDriverSupplier.java │ │ │ │ ├── FirefoxDriverSupplier.java │ │ │ │ ├── FirefoxDriverSupplierOnWindows.java │ │ │ │ ├── HeadlessFirefoxDriverSupplierOnLinux.java │ │ │ │ ├── HeadlessFirefoxDriverSupplierOnMacOs.java │ │ │ │ ├── InternetExplorerDriverSupplier.java │ │ │ │ ├── NaiveWebDriverFactory.java │ │ │ │ └── SafariDriverSupplier.java │ │ │ ├── chapter3 │ │ │ ├── ActionsTest.java │ │ │ ├── DiscoverMoreEventTest.java │ │ │ ├── TicketflyPage.java │ │ │ ├── TicketflyTest.java │ │ │ ├── inheritance │ │ │ │ ├── BaseTicketflyPage.java │ │ │ │ ├── TicketflyCareerPage.java │ │ │ │ ├── TicketflyEventPage.java │ │ │ │ ├── TicketflyHomePage.java │ │ │ │ └── TicketflyTest.java │ │ │ ├── interfaces │ │ │ │ ├── BaseTicketflyPage.java │ │ │ │ ├── ChangeLocation.java │ │ │ │ ├── TicketflyCareerPage.java │ │ │ │ ├── TicketflyEventPage.java │ │ │ │ ├── TicketflyHomePage.java │ │ │ │ └── TicketflyTest.java │ │ │ └── page │ │ │ │ ├── ChangeLocation.java │ │ │ │ ├── Page.java │ │ │ │ ├── TicketflyCareerPage.java │ │ │ │ ├── TicketflyEventPage.java │ │ │ │ ├── TicketflyHomePage.java │ │ │ │ └── TicketflyTest.java │ │ │ ├── chapter4 │ │ │ ├── ByConstants.java │ │ │ ├── GoogleAutoCompleteTest.java │ │ │ ├── NaiveJQueryHomePageTest.java │ │ │ ├── TicketflyTest.java │ │ │ └── unused │ │ │ │ └── TypeToLocateAnElement.java │ │ │ ├── chapter5 │ │ │ ├── JQueryHomePageTest.java │ │ │ ├── Menu.java │ │ │ ├── MenuGroupLocator.java │ │ │ ├── MouseOverMenuLocator.java │ │ │ └── NaiveJQueryHomePageTest.java │ │ │ ├── colm │ │ │ └── LambdaTest.java │ │ │ ├── converters │ │ │ └── ToMonthTest.java │ │ │ ├── cucumber │ │ │ ├── ChangeLocationStep.java │ │ │ ├── RunCucumberTest.java │ │ │ └── SelectCalendarStep.java │ │ │ ├── jbehave │ │ │ ├── AllStoryRunner.java │ │ │ ├── ChangeLocationStep.java │ │ │ └── SelectCalendarStep.java │ │ │ └── pages │ │ │ ├── BrowsersTest.java │ │ │ └── Person.java │ └── daugherty │ │ └── HomePageTest.java │ └── resources │ ├── com │ └── algocrafts │ │ ├── cucumber │ │ ├── change_location.feature │ │ ├── change_location_tabular.feature │ │ └── select_calendar.feature │ │ └── jbehave │ │ ├── change_location.story │ │ └── select_calendar.story │ ├── configuration-namespace.xml │ ├── configuration.xml │ ├── ftl │ └── custom-html-output.ftl │ ├── html │ ├── alert.html │ ├── confirm.html │ ├── date.html │ ├── iframeDemo.html │ ├── openWindow.html │ ├── package.json │ ├── prompt.html │ └── upload.html │ ├── logback-test.xml │ └── upload │ └── Test.log └── start-headless.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | *.iml 4 | src/main/resources/Firefox/ -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./start-headless.sh 3 | mvn clean install 4 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | java: 3 | version: oraclejdk8 4 | test: 5 | override: 6 | - mvn verify 7 | post: 8 | - mkdir -p $CIRCLE_TEST_REPORTS/junit/ 9 | - find . -type f -regex ".*/target/.*-reports/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; 10 | general: 11 | artifacts: 12 | - "target/screenshots" -------------------------------------------------------------------------------- /docs/Introducing BDD.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujunliang/seleniumcapsules/5b666d95ddb02a685b2d7f28d86ec149f0da365f/docs/Introducing BDD.pptx -------------------------------------------------------------------------------- /docs/Measuring TDD.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujunliang/seleniumcapsules/5b666d95ddb02a685b2d7f28d86ec149f0da365f/docs/Measuring TDD.pptx -------------------------------------------------------------------------------- /docs/What's New in Java 8.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujunliang/seleniumcapsules/5b666d95ddb02a685b2d7f28d86ec149f0da365f/docs/What's New in Java 8.pptx -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/Attemptable.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | public interface Attemptable { 4 | T attempt() throws Exception; 5 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/Duration.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class Duration { 6 | private final int duration; 7 | private final TimeUnit timeUnit; 8 | 9 | public Duration(int duration, TimeUnit timeUnit) { 10 | this.duration = duration; 11 | this.timeUnit = timeUnit; 12 | } 13 | 14 | public void elapse() { 15 | try { 16 | timeUnit.sleep(duration); 17 | } catch (InterruptedException e) { 18 | e.printStackTrace(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/PropertyDefinition.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import static java.util.concurrent.TimeUnit.SECONDS; 6 | 7 | public class PropertyDefinition { 8 | 9 | public int getCount() { 10 | return (byte) 3; 11 | } 12 | 13 | public int getInterval() { 14 | return 3; 15 | } 16 | 17 | public TimeUnit getTimeUnit() { 18 | return SECONDS; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/Retry.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | public class Retry { 6 | 7 | private boolean on; 8 | private long count; 9 | private final long interval; 10 | private final TimeUnit unit; 11 | 12 | /** 13 | * Construct a retry instance. 14 | * 15 | * @param count count 16 | * @param interval interval 17 | * @param unit unit 18 | */ 19 | public Retry(int count, int interval, TimeUnit unit) { 20 | this.count = count; 21 | this.interval = interval; 22 | this.unit = unit; 23 | } 24 | 25 | public boolean done() { 26 | return count <= 0 || !on; 27 | } 28 | 29 | public Retry on() { 30 | this.on = true; 31 | return this; 32 | } 33 | 34 | public Retry off() { 35 | this.on = false; 36 | return this; 37 | } 38 | 39 | public T attempt(Attemptable task) throws Exception { 40 | T result = perform(task); 41 | 42 | while (!done()) { 43 | rest(); 44 | result = perform(task); 45 | } 46 | return result; 47 | } 48 | 49 | private T perform(Attemptable task) throws Exception { 50 | count--; 51 | try { 52 | T attempt = task.attempt(); 53 | off(); 54 | return attempt; 55 | } catch (Exception e) { 56 | on(); 57 | e.printStackTrace(); 58 | if (count == 0) { 59 | throw e; 60 | } 61 | } 62 | return null; 63 | } 64 | 65 | public long count() { 66 | return count; 67 | } 68 | 69 | private void rest() { 70 | try { 71 | unit.sleep(interval); 72 | } catch (InterruptedException e) { 73 | e.printStackTrace(); 74 | } 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "retrying " + count + " times in " + interval + " " + unit; 80 | } 81 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/Retryable.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import static java.util.concurrent.TimeUnit.SECONDS; 6 | import static org.apache.log4j.Logger.getLogger; 7 | 8 | public interface Retryable { 9 | 10 | Logger LOGGER = getLogger(Retryable.class); 11 | 12 | default T retry(Attemptable task) { 13 | final Retry retry = new Retry(3, 3, SECONDS); 14 | try { 15 | return retry.attempt(task); 16 | } catch (Exception e) { 17 | LOGGER.info(retry); 18 | throw new RuntimeException(e); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/algorithm/SortedCounter.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.algorithm; 2 | 3 | import com.google.common.collect.HashMultimap; 4 | import com.google.common.collect.Multimap; 5 | import com.google.common.collect.TreeMultimap; 6 | 7 | import java.util.Collection; 8 | import java.util.Comparator; 9 | import java.util.Map; 10 | 11 | import static com.google.common.collect.Maps.newHashMap; 12 | 13 | public class SortedCounter { 14 | private final Map counter = newHashMap(); 15 | private final Multimap sortedCounter; 16 | 17 | public SortedCounter() { 18 | sortedCounter = HashMultimap.create(); 19 | } 20 | 21 | public SortedCounter(Comparator secondComparator) { 22 | sortedCounter = TreeMultimap.create( 23 | (count1, count2) -> count2.compareTo(count1), 24 | secondComparator); 25 | } 26 | 27 | public Collection collect() { 28 | return sortedCounter.values(); 29 | } 30 | 31 | public void count(T key) { 32 | Integer count = counter.get(key); 33 | sortedCounter.remove(count, key); 34 | 35 | count = count == null ? 1 : count + 1; 36 | counter.put(key, count); 37 | sortedCounter.put(count, key); 38 | } 39 | 40 | /** 41 | * Remove the first key and return it. 42 | * 43 | * @return the removed element 44 | * @throws java.util.NoSuchElementException if there is no value present 45 | */ 46 | public T removeFirst() { 47 | int firstCount = getFirst(sortedCounter.keySet()); 48 | T first = getFirst(sortedCounter.get(firstCount)); 49 | counter.remove(first); 50 | return first; 51 | } 52 | 53 | private E getFirst(Collection collection) { 54 | return collection.stream().findFirst().get(); 55 | } 56 | 57 | public boolean containsKey(T key) { 58 | return counter.containsKey(key); 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/Browsers.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | 4 | import com.algocrafts.selenium.Browser; 5 | import com.algocrafts.selenium.CachedWebDriverSupplier; 6 | import org.openqa.selenium.WebDriver; 7 | 8 | public enum Browsers implements Browser { 9 | 10 | FIREFOX(new FirefoxDriverSupplier()) , 11 | CHROME(new ChromeDriverSupplier()), 12 | HEADLESS_MAC(new HeadlessFirefoxDriverSupplierOnMacOs()), 13 | HEADLESS_LINUX(new HeadlessFirefoxDriverSupplierOnLinux()), 14 | SAFARI(new SafariDriverSupplier()), 15 | INTERNET_EXPLORER(new InternetExplorerDriverSupplier()); 16 | 17 | Browsers(CachedWebDriverSupplier driverDecorator) { 18 | this.webDriverSupplier = driverDecorator; 19 | } 20 | 21 | private final CachedWebDriverSupplier webDriverSupplier; 22 | 23 | public CachedWebDriverSupplier getSupplier() { 24 | return webDriverSupplier; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/ChromeDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | import org.openqa.selenium.chrome.ChromeOptions; 6 | 7 | public class ChromeDriverSupplier implements CachedWebDriverSupplier { 8 | 9 | @Override 10 | public ChromeDriver init() { 11 | ChromeOptions options = new ChromeOptions(); 12 | options.addArguments("--test-type"); 13 | return new ChromeDriver(options); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/FirefoxDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.firefox.FirefoxBinary; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | import org.openqa.selenium.firefox.FirefoxProfile; 7 | 8 | import java.io.File; 9 | 10 | public class FirefoxDriverSupplier implements CachedWebDriverSupplier { 11 | @Override 12 | public FirefoxDriver init() { 13 | return new FirefoxDriver(); 14 | // FirefoxBinary binary = new FirefoxBinary(new File("src/main/resources/Firefox/Contents/MacOS/firefox-bin")); 15 | // FirefoxProfile profile = new FirefoxProfile(new File("src/main/resources/Firefox/Profiles/default")); 16 | // return new FirefoxDriver(binary, profile); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/FirefoxDriverSupplierOnWindows.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | import com.algocrafts.selenium.CachedWebDriverSupplier; 5 | import org.openqa.selenium.firefox.FirefoxBinary; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | import org.openqa.selenium.firefox.FirefoxProfile; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * This class is not one of the enum constants enum Browsers. It is used to demonstrate how to implement the Browser 13 | * interface thus used as the constructor parameter for AbstractPage. It is declared as a bean in spring context file, 14 | *

15 | * <bean id="firefox" class="com.algocrafts.browsers.FirefoxOnWindows"/> 16 | *

17 | * and it is referenced by ref attribute of the containing bean. 18 | *

19 | * However, the enum browser is referenced by value, 20 | * <constructor-arg value="${browser}"/> 21 | *

22 | * in property file, 23 | * browser=CHROME 24 | *

25 | * The other browsers known to enum don't implement Browser interface, they just implement WebDriverSupplier<T> 26 | */ 27 | public class FirefoxDriverSupplierOnWindows implements Browser { 28 | 29 | public FirefoxDriver init() { 30 | FirefoxBinary binary = new FirefoxBinary(new File("src/main/resources/Firefox/firefox.exe")); 31 | FirefoxProfile profile = new FirefoxProfile(new File("src/main/resources/Firefox/Profiles/default")); 32 | return new FirefoxDriver(binary, profile); 33 | } 34 | 35 | @Override 36 | public CachedWebDriverSupplier getSupplier() { 37 | return this; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/HeadlessFirefoxDriverSupplierOnLinux.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.firefox.FirefoxBinary; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | import org.openqa.selenium.firefox.FirefoxProfile; 7 | 8 | import java.io.File; 9 | 10 | 11 | public class HeadlessFirefoxDriverSupplierOnLinux implements CachedWebDriverSupplier { 12 | @Override 13 | public FirefoxDriver init() { 14 | FirefoxBinary binary = new FirefoxBinary(new File("/opt/local/lib/firefox-x11/firefox-bin")); 15 | binary.setEnvironmentProperty("DISPLAY", ":88"); 16 | return new FirefoxDriver(binary, new FirefoxProfile()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/HeadlessFirefoxDriverSupplierOnMacOs.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.firefox.FirefoxBinary; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | import org.openqa.selenium.firefox.FirefoxProfile; 7 | 8 | import java.io.File; 9 | 10 | 11 | public class HeadlessFirefoxDriverSupplierOnMacOs implements CachedWebDriverSupplier { 12 | @Override 13 | public FirefoxDriver init() { 14 | FirefoxBinary binary = new FirefoxBinary(new File("/opt/local/lib/firefox-x11/firefox-bin")); 15 | binary.setEnvironmentProperty("DISPLAY", ":88"); 16 | return new FirefoxDriver(binary, new FirefoxProfile()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/InternetExplorerDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.ie.InternetExplorerDriver; 5 | 6 | 7 | public class InternetExplorerDriverSupplier implements CachedWebDriverSupplier { 8 | @Override 9 | public InternetExplorerDriver init() { 10 | return new InternetExplorerDriver(); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/browsers/SafariDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.browsers; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.safari.SafariDriver; 5 | 6 | public class SafariDriverSupplier implements CachedWebDriverSupplier { 7 | @Override 8 | public SafariDriver init() { 9 | return new SafariDriver(); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/Button.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.clickables; 2 | 3 | 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | import com.algocrafts.selenium.SearchScope; 7 | 8 | public class Button> extends Clickables { 9 | 10 | public Button(T where, Locator locator) { 11 | super(where, locator); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/Clickables.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.clickables; 2 | 3 | import com.algocrafts.selenium.Clickable; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | import com.algocrafts.selenium.SearchScope; 7 | import org.slf4j.Logger; 8 | 9 | import static org.slf4j.LoggerFactory.getLogger; 10 | 11 | public class Clickables> implements Clickable { 12 | 13 | private static final Logger log = getLogger(Clickables.class); 14 | private final T where; 15 | private final Locator locator; 16 | 17 | public Clickables(T where, Locator locator) { 18 | this.locator = locator; 19 | this.where = where; 20 | } 21 | 22 | @Override 23 | public void click() { 24 | Element menu = locator.locate(where); 25 | log.info("clicking [" + menu + "]"); 26 | menu.click(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return locator.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/ImageButton.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.clickables; 2 | 3 | 4 | import com.algocrafts.selenium.SearchScope; 5 | 6 | public class ImageButton> extends Button { 7 | 8 | public ImageButton(T where, String fileName, int index) { 9 | super(where, finder -> finder.image(fileName, index)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/Link.java: -------------------------------------------------------------------------------- 1 | 2 | package com.algocrafts.clickables; 3 | 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.SearchScope; 6 | import com.algocrafts.selenium.Locator; 7 | 8 | public class Link> extends Clickables { 9 | 10 | public Link(T where, Locator locator) { 11 | super(where, locator); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/Menu.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.clickables; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Locator; 5 | import com.algocrafts.selenium.Element; 6 | 7 | public class Menu extends Button { 8 | 9 | public Menu(Page page, Locator locator) { 10 | super(page, locator); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/clickables/Url.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.clickables; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | import com.algocrafts.selenium.Clickable; 5 | import org.slf4j.Logger; 6 | 7 | import static org.slf4j.LoggerFactory.getLogger; 8 | 9 | public class Url implements Clickable { 10 | 11 | private static final Logger log = getLogger(Url.class); 12 | 13 | private T browser; 14 | private String url; 15 | 16 | public Url(T browser, String url) { 17 | this.browser = browser; 18 | this.url = url; 19 | } 20 | 21 | public void click() { 22 | log.info("loading [" + url + "]"); 23 | browser.get(url); 24 | browser.save(url); 25 | } 26 | 27 | public T load() { 28 | click(); 29 | return browser; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/ElementPredicates.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | import com.algocrafts.selenium.Element; 4 | 5 | import java.util.function.Predicate; 6 | 7 | public enum ElementPredicates implements Predicate { 8 | NOT_NULL { 9 | @Override 10 | public boolean test(Element input) { 11 | return input != null; 12 | } 13 | }, 14 | DISPLAYED { 15 | @Override 16 | public boolean test(Element input) { 17 | return input.isDisplayed(); 18 | } 19 | }, 20 | ENABLED { 21 | @Override 22 | public boolean test(Element input) { 23 | return input.isEnabled(); 24 | } 25 | }, 26 | SELECTED { 27 | @Override 28 | public boolean test(Element input) { 29 | return input.isSelected(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/Equals.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | import java.util.function.Predicate; 4 | 5 | public class Equals implements Predicate { 6 | private final String string; 7 | 8 | public Equals(Object o) { 9 | this.string = o.toString(); 10 | } 11 | 12 | @Override 13 | public boolean test(String input) { 14 | return input.equals(string); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/HasElements.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | 4 | import java.util.function.Predicate; 5 | import java.util.stream.Stream; 6 | 7 | public class HasElements implements Predicate> { 8 | 9 | @Override 10 | public boolean test(Stream stream) { 11 | return stream.count() > 0; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/OptionalPresents.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | import com.algocrafts.selenium.Element; 4 | 5 | import java.util.Optional; 6 | import java.util.function.Predicate; 7 | 8 | /** 9 | * Created by yujunliang on 7/26/14. 10 | */ 11 | public enum OptionalPresents implements Predicate>{ 12 | PRESENT; 13 | 14 | @Override 15 | public boolean test(Optional elementOptional) { 16 | return elementOptional.isPresent(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/PagePredicates.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | import com.algocrafts.locators.Locators; 4 | import com.algocrafts.pages.Page; 5 | 6 | import java.util.function.Predicate; 7 | 8 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 9 | import static com.algocrafts.conditions.ElementPredicates.NOT_NULL; 10 | import static com.algocrafts.conditions.OptionalPresents.PRESENT; 11 | import static com.algocrafts.conditions.StringEquals.*; 12 | import static com.algocrafts.converters.GetText.TEXT; 13 | import static com.algocrafts.converters.OptionalGetter.GET; 14 | import static com.algocrafts.locators.Locators.element; 15 | import static com.algocrafts.selectors.Id.CONTENT; 16 | import static com.algocrafts.selectors.Id.EXTJS_CALENDAR; 17 | import static com.algocrafts.selectors.Id.UI_DATEPICKER_DIV; 18 | import static com.algocrafts.selectors.TagName.*; 19 | import static com.bookstore.BookStoreId.*; 20 | 21 | public enum PagePredicates implements Predicate { 22 | REACHED_CALENDAR_PAGE( 23 | Locators.element(CONTENT) 24 | .andThen(element(H1)) 25 | .andThen(TEXT) 26 | .and(DATEPICKER) 27 | ), 28 | SHOPPING_CART_DISPLAYED( 29 | Locators.element(SHOPPING_CART) 30 | .and(NOT_NULL.and(DISPLAYED)) 31 | ), 32 | YAHOO_COPYRIGHTED( 33 | Locators.element(YAHOO_COPYRIGHT) 34 | .andThen(element(EM)) 35 | .andThen(TEXT) 36 | .and(YAHOO) 37 | ), 38 | IS_COPYRIGHTED( 39 | Locators.element(FOOTER) 40 | .andThen(element(P)) 41 | .andThen(element(I)) 42 | .andThen(TEXT) 43 | .and(MANNING) 44 | ), 45 | EXTJS_CALENDAR_NOT_DISPLAYED( 46 | Locators.optionalElement(EXTJS_CALENDAR) 47 | .and(PRESENT.negate().or(GET.and(DISPLAYED.negate())))) 48 | , 49 | JQUERY_CALENDAR_NOT_DISPLAYED( 50 | Locators.optionalElement(UI_DATEPICKER_DIV) 51 | .and(PRESENT.negate().or(GET.and(DISPLAYED.negate()))) 52 | ); 53 | private final Predicate predicate; 54 | 55 | PagePredicates(Predicate predicate) { 56 | this.predicate = predicate; 57 | } 58 | 59 | @Override 60 | public boolean test(Page page) { 61 | return predicate.test(page); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/StringContains.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | 4 | import java.util.function.Predicate; 5 | 6 | public class StringContains implements Predicate { 7 | private final String string; 8 | 9 | public StringContains(String string) { 10 | this.string = string; 11 | } 12 | 13 | @Override 14 | public boolean test(String input) { 15 | return input.contains(string); 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/conditions/StringEquals.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.conditions; 2 | 3 | import java.util.function.Predicate; 4 | 5 | public enum StringEquals implements Predicate { 6 | 7 | TRUE("true"), 8 | YAHOO("Copyright © 2015 Yahoo Inc. All rights reserved."), 9 | MANNING("© 2003-2015 Manning Publications Co."), 10 | DATEPICKER("Datepicker"); 11 | 12 | private final String text; 13 | 14 | StringEquals(String text) { 15 | this.text = text; 16 | } 17 | 18 | @Override 19 | public boolean test(String element) { 20 | return text.equals(element); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/ElementAtIndex.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import java.util.List; 7 | 8 | public class ElementAtIndex implements Locator, T> { 9 | 10 | private final int index; 11 | 12 | public ElementAtIndex(int index) { 13 | this.index = index; 14 | } 15 | 16 | @Override 17 | public T locate(List list) { 18 | return list.get(index); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/ElementFunctions.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.Locator; 5 | 6 | public enum ElementFunctions implements Locator { 7 | 8 | CLICK { 9 | @Override 10 | public Void locate(Element input) { 11 | input.click(); 12 | return null; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/Filter.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import java.util.function.Predicate; 7 | import java.util.stream.Stream; 8 | 9 | public class Filter implements Locator, Stream> { 10 | 11 | private final Predicate predicate; 12 | 13 | public Filter(Predicate predicate) { 14 | this.predicate = predicate; 15 | } 16 | 17 | @Override 18 | public Stream locate(Stream elements) { 19 | return elements.filter(predicate); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/FirstItem.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import java.util.Optional; 7 | import java.util.stream.Stream; 8 | 9 | public class FirstItem implements Locator, Optional> { 10 | 11 | @Override 12 | public Optional locate(Stream elements) { 13 | return elements.findFirst(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/FirstMatch.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.selenium.Locator; 4 | 5 | import java.util.Optional; 6 | import java.util.function.Predicate; 7 | import java.util.stream.Stream; 8 | 9 | public class FirstMatch implements Locator, Optional> { 10 | 11 | private final Predicate predicate; 12 | 13 | public FirstMatch(Predicate predicate) { 14 | this.predicate = predicate; 15 | } 16 | 17 | @Override 18 | public Optional locate(Stream stream) { 19 | return new Filter<>(predicate).andThen(new FirstItem<>()).locate(stream); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/FrameLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Locator; 5 | 6 | public class FrameLocator implements Locator { 7 | 8 | private final int index; 9 | 10 | public FrameLocator(int index) { 11 | this.index = index; 12 | } 13 | 14 | @Override 15 | public Page locate(Page page) { 16 | return page.frame(index); 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "frames[" + index + "]"; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/GetText.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.locators.ElementLocator; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | 7 | import static com.algocrafts.selectors.TagName.A; 8 | 9 | public enum GetText implements Locator { 10 | CHECKED { 11 | @Override 12 | public String locate(Element input) { 13 | return input.getAttribute("checked"); 14 | } 15 | }, 16 | VALUE { 17 | @Override 18 | public String locate(Element input) { 19 | return input.getAttribute("value"); 20 | } 21 | }, 22 | SRC { 23 | @Override 24 | public String locate(Element input) { 25 | return input.getAttribute("src"); 26 | } 27 | }, 28 | TEXT { 29 | @Override 30 | public String locate(Element input) { 31 | return input.getText(); 32 | } 33 | }, 34 | LINK_TEXT { 35 | @Override 36 | public String locate(Element input) { 37 | return new ElementLocator(A).andThen(TEXT).locate(input); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/OptionalGetter.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import java.util.Optional; 7 | 8 | public enum OptionalGetter implements Locator, Element>{ 9 | GET; 10 | 11 | @Override 12 | public Element locate(Optional element) { 13 | return element.get(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/Ordinal.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | public enum Ordinal implements Locator { 7 | 8 | ORDINAL { 9 | @Override 10 | public Integer locate(Enum input) { 11 | return input.ordinal(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/StreamToList.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import java.util.List; 7 | import java.util.stream.Stream; 8 | 9 | import static java.util.stream.Collectors.toList; 10 | 11 | public class StreamToList implements Locator, List> { 12 | 13 | @Override 14 | public List locate(Stream element) { 15 | return element.collect(toList()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/StringConverter.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | public enum StringConverter implements Locator { 7 | FIRST_HALF { 8 | @Override 9 | public String locate(String element) { 10 | return element.split(" ")[0]; 11 | } 12 | }, 13 | SECOND_HALF { 14 | @Override 15 | public String locate(String element) { 16 | return element.split(" ")[1]; 17 | } 18 | }, 19 | RESTORE_UNDERSCORE { 20 | @Override 21 | public String locate(String element) { 22 | return element.replace(' ', '_'); 23 | } 24 | }, 25 | 26 | REPLACE_UNDERSCORE { 27 | @Override 28 | public String locate(String element) { 29 | return element.replace('_', ' '); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/StringToInt.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | 4 | import com.algocrafts.selenium.Locator; 5 | 6 | import static java.lang.Integer.parseInt; 7 | 8 | public enum StringToInt implements Locator { 9 | 10 | PARSE_INT { 11 | @Override 12 | public Integer locate(String element) { 13 | return parseInt(element); 14 | } 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/converters/StringToMonth.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import com.algocrafts.objectcache.OneKeyLFUPolicy; 4 | import com.algocrafts.objectcache.SelfPopulatingCache; 5 | import com.algocrafts.selenium.Locator; 6 | 7 | import java.time.Month; 8 | 9 | import static com.algocrafts.objectcache.SelfPopulatingCache.Creator; 10 | import static com.algocrafts.converters.StringToMonth.MonthMapper.MONTH_MAPPER; 11 | 12 | public enum StringToMonth implements Locator { 13 | 14 | TO_MONTH; 15 | 16 | @Override 17 | public Month locate(String element) { 18 | return maps.valueOf(element.toUpperCase()); 19 | } 20 | 21 | private static final SelfPopulatingCache maps = new SelfPopulatingCache<>(48, new OneKeyLFUPolicy<>(), MONTH_MAPPER); 22 | 23 | enum MonthMapper implements Creator { 24 | MONTH_MAPPER; 25 | 26 | @Override 27 | public Month create(String key) { 28 | 29 | Month month = null; 30 | try { 31 | month = Month.valueOf(key); 32 | } catch (IllegalArgumentException e) { 33 | String newKey; 34 | if (key.contains(".")) { 35 | newKey = key.replace(".", ""); 36 | } else { 37 | newKey = key; 38 | } 39 | for (Month m : Month.values()) { 40 | if (m.name().contains(newKey)) { 41 | return m; 42 | } 43 | } 44 | } 45 | return month; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/datepicker/CalendarPicker.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.datepicker; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Locator; 5 | 6 | public class CalendarPicker { 7 | 8 | private final Page browser; //<1> 9 | private final Locator previous; //<2> 10 | private final Locator next; //<3> 11 | private final Locator displayedValue; //<4> 12 | 13 | public CalendarPicker(Page browser, 14 | Locator previous, 15 | Locator next, 16 | Locator displayedValue) { //<5> 17 | this.browser = browser; 18 | this.previous = previous; 19 | this.next = next; 20 | this.displayedValue = displayedValue; 21 | } 22 | 23 | /** 24 | * 25 | * @param flipTo 26 | */ 27 | void pick(int flipTo) { 28 | int difference = displayedValue.apply(browser) - flipTo; 29 | if (difference < 0) { 30 | for (int i = difference; i < 0; i++) { 31 | next.apply(browser); 32 | } 33 | } else if (difference > 0) { 34 | for (int i = 0; i < difference; i++) { 35 | previous.apply(browser); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/datepicker/Datepicker.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.datepicker; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selenium.Locator; 6 | 7 | import java.time.LocalDate; 8 | import java.time.Month; 9 | 10 | /** 11 | * A general purpose DatePicker can be used to pick a given date from 12 | * the calendar flyout provided by JavaScript framework. 13 | * 14 | * @author Yujun Liang 15 | * @since 0.1 16 | */ 17 | public class Datepicker { 18 | 19 | private final Page browser; //<1> 20 | private final Locator trigger; //<2> 21 | private final CalendarPicker yearPicker; //<3> 22 | private final CalendarPicker monthPicker; //<4> 23 | private final DayPicker dayPicker; //<5> 24 | 25 | /** 26 | * Constructor of the DatePicker which taking a Calendar interface. 27 | * 28 | * @param browser 29 | * @param trigger 30 | * @param yearPicker 31 | * @param monthPicker 32 | * @param dayPicker 33 | */ 34 | public Datepicker(Page browser, 35 | Locator trigger, 36 | CalendarPicker yearPicker, 37 | CalendarPicker monthPicker, 38 | DayPicker dayPicker) { //<6> 39 | this.browser = browser; 40 | this.trigger = trigger; 41 | this.yearPicker = yearPicker; 42 | this.monthPicker = monthPicker; 43 | this.dayPicker = dayPicker; 44 | } 45 | 46 | /** 47 | * Pick a date by the given parameter. 48 | * for example, 49 | * datePicker.pick(Month.JULY, 31, 1999) 50 | * 51 | * @param month it need to be defined as an enum to make the code cleaner. 52 | * @param day an integer representing the day appearing on the calendar 53 | * @param year an ineger representing the year appearing on the calendar 54 | */ 55 | public void pick(Month month, int day, int year) { //<7> 56 | LocalDate.of(year, month.ordinal() + 1, day); //<8> 57 | trigger.apply(browser); //<9> 58 | yearPicker.pick(year); //<10> 59 | monthPicker.pick(month.ordinal()); //<11> 60 | dayPicker.pick(day); //<12> 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/datepicker/DayPicker.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.datepicker; 2 | 3 | 4 | public interface DayPicker { 5 | 6 | void pick(int day); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/domain/Countries.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.domain; 2 | 3 | 4 | import static com.algocrafts.converters.StringConverter.REPLACE_UNDERSCORE; 5 | import static com.algocrafts.converters.StringConverter.RESTORE_UNDERSCORE; 6 | 7 | public enum Countries { 8 | Australia, 9 | China, 10 | India, 11 | United_Kindon, 12 | United_States; 13 | 14 | @Override 15 | public String toString() { 16 | return REPLACE_UNDERSCORE.locate(this.name()); 17 | } 18 | 19 | public static Countries fromString(String string) { 20 | return valueOf(RESTORE_UNDERSCORE.locate(string)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/domain/CreditCardType.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.domain; 2 | 3 | import static com.algocrafts.converters.StringConverter.REPLACE_UNDERSCORE; 4 | import static com.algocrafts.converters.StringConverter.RESTORE_UNDERSCORE; 5 | 6 | public enum CreditCardType { 7 | 8 | American_Express, 9 | JCB, 10 | MasterCard, 11 | Visa, 12 | Discover; 13 | 14 | @Override 15 | public String toString() { 16 | return REPLACE_UNDERSCORE.locate(this.name()); 17 | } 18 | 19 | public static CreditCardType fromString(String string) { 20 | return valueOf(RESTORE_UNDERSCORE.locate(string)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/domain/SetDiff.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.domain; 2 | 3 | 4 | import java.util.Set; 5 | 6 | import static com.google.common.collect.Sets.newHashSet; 7 | 8 | public class SetDiff { 9 | 10 | private String diff; 11 | private final Set expected; 12 | private final Set actual; 13 | 14 | public SetDiff(String info, Set expected, Set actual) { 15 | this.diff = info; 16 | this.expected = expected; 17 | this.actual = actual; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | if (actual.size() > 0) { 23 | diff += "\nactual results,\n" + actual + "\n"; 24 | } 25 | Set onlyInExpected = newHashSet(expected); 26 | onlyInExpected.removeAll(actual); 27 | actual.removeAll(expected); 28 | 29 | if (actual.size() > 0) { 30 | diff += "\nunexpected results appeared in actual,\n" + 31 | actual + "\n"; 32 | } 33 | if (onlyInExpected.size() > 0) { 34 | diff += "\nexpected results not found in actual,\n" + 35 | onlyInExpected + "\n"; 36 | } 37 | return diff; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/domain/UnitedStates.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.domain; 2 | 3 | import static com.algocrafts.converters.StringConverter.REPLACE_UNDERSCORE; 4 | import static com.algocrafts.converters.StringConverter.RESTORE_UNDERSCORE; 5 | 6 | public enum UnitedStates { 7 | Alabama("AL"), 8 | Montana("MT"), 9 | Alaska("AK"), 10 | Nebraska("NE"), 11 | Arizona("AZ"), 12 | Nevada("NV"), 13 | Arkansas("AR"), 14 | New_Hampshire("NH"), 15 | California("CA"), 16 | New_Jersey("NJ"), 17 | Colorado("CO"), 18 | New_Mexico("NM"), 19 | Connecticut("CT"), 20 | New_York("NY"), 21 | Delaware("DE"), 22 | North_Carolina("NC"), 23 | Florida("FL"), 24 | North_Dakota("ND"), 25 | Georgia("GA"), 26 | Ohio("OH"), 27 | Hawaii("HI"), 28 | Oklahoma("OK"), 29 | Idaho("ID"), 30 | Oregon("OR"), 31 | Illinois("IL"), 32 | Pennsylvania("PA"), 33 | Indiana("IN"), 34 | Rhode_Island("RI"), 35 | Iowa("IA"), 36 | South_Carolina("SC"), 37 | Kansas("KS"), 38 | South_Dakota("SD"), 39 | Kentucky("KY"), 40 | Tennessee("TN"), 41 | Louisiana("LA"), 42 | Texas("TX"), 43 | Maine("ME"), 44 | Utah("UT"), 45 | Maryland("MD"), 46 | Vermont("VT"), 47 | Massachusetts("MA"), 48 | Virginia("VA"), 49 | Michigan("MI"), 50 | Washington("WA"), 51 | Minnesota("MN"), 52 | West_Virginia("WV"), 53 | Mississippi("MS"), 54 | Wisconsin("WI"), 55 | Missouri("MO"), 56 | Wyoming("WY"); 57 | 58 | private final String value; 59 | 60 | private UnitedStates(String value) { 61 | this.value = value; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return REPLACE_UNDERSCORE.locate(this.name()); 67 | } 68 | 69 | public static UnitedStates fromString(String string) { 70 | return valueOf(RESTORE_UNDERSCORE.locate(string)); 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/forms/Checkbox.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.forms; 2 | 3 | 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locating; 6 | import com.algocrafts.selenium.SearchScope; 7 | import org.openqa.selenium.By; 8 | 9 | import java.util.function.Supplier; 10 | 11 | import static com.algocrafts.conditions.StringEquals.TRUE; 12 | import static com.algocrafts.converters.GetText.CHECKED; 13 | import static com.algocrafts.locators.Locators.element; 14 | 15 | public class Checkbox> 16 | extends Locating { 17 | 18 | /** 19 | * Constructor of the checkbox. 20 | * 21 | * @param where the place the checkbox can be found 22 | * @param selector the selector that leads to the checkbox 23 | */ 24 | public Checkbox(final T where, Supplier selector) { 25 | super(where, element(selector)); 26 | } 27 | 28 | /** 29 | * Change the checkbox according to the value parameter 30 | * 31 | * @param value true or false 32 | */ 33 | public void setValue(boolean value) { 34 | locate((Element checkbox) -> { 35 | if (checkbox != null && checkbox.isSelected() != value) { 36 | checkbox.click(); 37 | } 38 | return null; 39 | }); 40 | } 41 | 42 | /** 43 | * @return whether the checkbox is checked or not 44 | */ 45 | public boolean isChecked() { 46 | return test(CHECKED.and(TRUE)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/forms/FileInput.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.forms; 2 | 3 | 4 | import com.algocrafts.algorithm.Retry; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.selenium.Element; 7 | import com.algocrafts.selenium.Locating; 8 | import com.algocrafts.selenium.SearchScope; 9 | import org.openqa.selenium.By; 10 | import org.slf4j.Logger; 11 | 12 | import java.io.File; 13 | import java.util.Optional; 14 | import java.util.function.Supplier; 15 | 16 | import static com.algocrafts.converters.OptionalGetter.GET; 17 | import static java.util.concurrent.TimeUnit.SECONDS; 18 | import static org.slf4j.LoggerFactory.getLogger; 19 | 20 | public class FileInput> extends Locating> { 21 | 22 | public static final Logger log = getLogger(FileInput.class); 23 | 24 | /** 25 | * Constructor of the input field. 26 | * 27 | * @param where where 28 | * @param selector selector 29 | */ 30 | public FileInput(T where, Supplier selector) { 31 | super(where, Locators.optionalElement(selector)); 32 | } 33 | 34 | public void put(File file) { 35 | final Retry retry = new Retry(5, 1, SECONDS); 36 | try { 37 | retry.attempt(() -> { 38 | Element element = locate(GET); 39 | element.sendKeys(file.getAbsolutePath()); 40 | return null; 41 | }); 42 | } catch (Exception e) { 43 | log.info("Failed to set file {}", file); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/forms/RadioButton.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.forms; 2 | 3 | 4 | import com.algocrafts.conditions.StringContains; 5 | import com.algocrafts.converters.FirstMatch; 6 | import com.algocrafts.selenium.Element; 7 | import com.algocrafts.selenium.Locating; 8 | import com.algocrafts.selenium.SearchScope; 9 | import org.openqa.selenium.By; 10 | 11 | import java.util.function.Supplier; 12 | import java.util.stream.Stream; 13 | 14 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 15 | import static com.algocrafts.conditions.StringEquals.TRUE; 16 | import static com.algocrafts.converters.ElementFunctions.CLICK; 17 | import static com.algocrafts.converters.GetText.CHECKED; 18 | import static com.algocrafts.converters.GetText.VALUE; 19 | import static com.algocrafts.converters.OptionalGetter.GET; 20 | import static com.algocrafts.locators.Locators.elements; 21 | 22 | public class RadioButton> 23 | extends Locating> { 24 | 25 | /** 26 | * Constructor this radio button. 27 | * 28 | * @param where where 29 | * @param selector selector 30 | */ 31 | public RadioButton(T where, Supplier selector) { 32 | super(where, elements(selector)); 33 | } 34 | 35 | /** 36 | * @param value value to set 37 | */ 38 | public void setValue(Object value) { 39 | locate(new FirstMatch<>(VALUE.and(new StringContains(value.toString()))) 40 | .andThen(GET).andThen(CLICK)); 41 | } 42 | 43 | /** 44 | * @return the value of the select radio 45 | */ 46 | public String getValue() { 47 | return locate(new FirstMatch<>(DISPLAYED 48 | .and(CHECKED.and(TRUE))) 49 | .andThen(GET) 50 | .andThen(VALUE)); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/locators/ElementLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.locators; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.SearchScope; 5 | import org.openqa.selenium.By; 6 | 7 | import java.util.function.Supplier; 8 | 9 | public class ElementLocator> 10 | extends Locators { 11 | 12 | public ElementLocator(Supplier selector) { 13 | super((T where) -> where.untilFound(selector)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/locators/ElementsLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.locators; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.SearchScope; 5 | import org.openqa.selenium.By; 6 | 7 | import java.util.function.Supplier; 8 | import java.util.stream.Stream; 9 | 10 | public class ElementsLocator> 11 | extends Locators> { 12 | 13 | public ElementsLocator(Supplier selector) { 14 | super((T where) 15 | -> where.findElements(selector) 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/locators/Locators.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.locators; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.Locator; 5 | import com.algocrafts.selenium.SearchScope; 6 | import org.openqa.selenium.By; 7 | 8 | import java.util.Optional; 9 | import java.util.function.Supplier; 10 | import java.util.stream.Stream; 11 | 12 | public class Locators, T2> 13 | implements Locator { 14 | 15 | public static > Locators element(Supplier selector) { 16 | return new ElementLocator<>(selector); 17 | } 18 | 19 | public static > Locators> elements(Supplier selector) { 20 | return new ElementsLocator<>(selector); 21 | } 22 | 23 | public static > Locators> optionalElement(Supplier selector) { 24 | return new OptionalElementLocator<>(selector); 25 | } 26 | 27 | public static SelectLocator select(Supplier selector) { 28 | return new SelectLocator(selector); 29 | } 30 | 31 | private final Locator locator; 32 | 33 | public Locators(Locator locator) { 34 | this.locator = locator; 35 | } 36 | 37 | @Override 38 | public T2 locate(T1 where) { 39 | return locator.locate(where); 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/locators/OptionalElementLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.locators; 2 | 3 | import com.algocrafts.selenium.Element; 4 | import com.algocrafts.selenium.SearchScope; 5 | import org.openqa.selenium.By; 6 | 7 | import java.util.Optional; 8 | import java.util.function.Supplier; 9 | 10 | public class OptionalElementLocator> 11 | extends Locators> { 12 | 13 | public OptionalElementLocator(Supplier selector) { 14 | super((T where) -> 15 | where.optionalElement(selector) 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/locators/SelectLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.locators; 2 | 3 | import com.algocrafts.conditions.HasElements; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.SearchScope; 6 | import org.openqa.selenium.By; 7 | 8 | import org.openqa.selenium.NoSuchElementException; 9 | import org.openqa.selenium.support.ui.Select; 10 | import org.slf4j.Logger; 11 | 12 | import java.util.function.Supplier; 13 | 14 | import static com.algocrafts.selectors.TagName.OPTION; 15 | import static org.slf4j.LoggerFactory.getLogger; 16 | 17 | 18 | public class SelectLocator> 19 | extends Locators { 20 | 21 | private static final Logger log = getLogger(SelectLocator.class); 22 | 23 | public SelectLocator(Supplier selector) { 24 | super((T where) -> { 25 | final Element element = where.untilFound(selector); 26 | try { 27 | element.until(Locators.elements(OPTION).and(new HasElements<>())); 28 | return new Select(element); 29 | } catch (NoSuchElementException e) { 30 | element.click(); 31 | where.onTimeout(); 32 | log.error("Timeout waiting for the option list to populate.", e); 33 | throw e; 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/objectcache/OneKeyCachePolicy.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.objectcache; 2 | 3 | public interface OneKeyCachePolicy { 4 | K evictingKey(boolean cacheIsFull, K key); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/objectcache/OneKeyLFUPolicy.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.objectcache; 2 | 3 | 4 | import com.algocrafts.algorithm.SortedCounter; 5 | 6 | public class OneKeyLFUPolicy implements OneKeyCachePolicy { 7 | private final SortedCounter sortedCounter = new SortedCounter<>(); 8 | 9 | @Override 10 | public K evictingKey(boolean cacheIsFull, K key) { 11 | K LFU = null; 12 | if (cacheIsFull && !sortedCounter.containsKey(key)) { 13 | LFU = sortedCounter.removeFirst(); 14 | } 15 | sortedCounter.count(key); 16 | return LFU; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/objectcache/OneKeyLRUPolicy.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.objectcache; 2 | 3 | 4 | import java.util.Iterator; 5 | import java.util.LinkedHashSet; 6 | import java.util.Set; 7 | 8 | public class OneKeyLRUPolicy implements OneKeyCachePolicy { 9 | private final Set accessLog = new LinkedHashSet<>(); 10 | 11 | @Override 12 | public K evictingKey(boolean cacheIsFull, K key) { 13 | K LRU = null; 14 | if (cacheIsFull && !accessLog.remove(key)) { 15 | Iterator iterator = accessLog.iterator(); 16 | LRU = iterator.next(); 17 | iterator.remove(); 18 | } 19 | accessLog.add(key); 20 | return LRU; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/objectcache/SelfPopulatingCache.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.objectcache; 2 | 3 | 4 | import java.util.Collection; 5 | import java.util.Map; 6 | 7 | import static com.google.common.collect.Maps.newHashMap; 8 | 9 | public class SelfPopulatingCache { 10 | 11 | private final int maxSize; 12 | private final OneKeyCachePolicy cachePolicy; 13 | private final Map cache = newHashMap(); 14 | private final Creator creator; 15 | 16 | public static SelfPopulatingCache create(Creator creator) { 17 | return new SelfPopulatingCache<>(creator); 18 | } 19 | 20 | public SelfPopulatingCache(Creator creator) { 21 | this(10, new OneKeyLFUPolicy<>(), creator); 22 | } 23 | 24 | public SelfPopulatingCache(int maxSize, OneKeyCachePolicy cachePolicy, Creator creator) { 25 | this.maxSize = maxSize; 26 | this.cachePolicy = cachePolicy; 27 | this.creator = creator; 28 | } 29 | 30 | public V valueOf(K key) { 31 | K evict = cachePolicy.evictingKey(cache.size() == maxSize, key); 32 | if (evict != null) { 33 | cache.remove(evict); 34 | } 35 | V value = cache.get(key); 36 | if (value == null) { 37 | value = creator.create(key); 38 | if (value != null) { 39 | cache.put(key, value); 40 | } 41 | } 42 | return value; 43 | } 44 | 45 | public void remove(K key) { 46 | cache.remove(key); 47 | } 48 | 49 | public Collection values() { 50 | return cache.values(); 51 | } 52 | 53 | public interface Creator { 54 | V create(K key); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/ClassName.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | 8 | import static org.openqa.selenium.By.className; 9 | 10 | /** 11 | * This enum is a Supplier of ByClassName from Selenium By API. 12 | */ 13 | public enum ClassName implements Supplier { 14 | 15 | L_TINYNAL1("l_tinynav1"), 16 | SF_JS_ENABLED("sf-js-enabled"), 17 | TOOLS_LOCATION("tools-location"), 18 | 19 | UI_DATEPICKER_CALENDAR("ui-datepicker-calendar"), 20 | UI_DATEPICKER_NEXT("ui-datepicker-next"), 21 | UI_DATEPICKER_PREV("ui-datepicker-prev"), 22 | UI_DATEPICKER_MONTH("ui-datepicker-month"), 23 | UI_DATEPICKER_YEAR("ui-datepicker-year"), 24 | UI_DATEPICKER_HEADER("ui-datepicker-header"), 25 | 26 | 27 | PAGE_TITLE("page-title"), 28 | UI_DATEPICKER_CLOSE("ui-datepicker-close"), 29 | SBDD_B("sbdd_b"), 30 | MAIN("main"); 31 | 32 | private final By by; 33 | 34 | ClassName(String id) { 35 | this.by = className(id); 36 | } 37 | 38 | /** 39 | * @return the by instance variable which is a ByClassName. 40 | */ 41 | @Override 42 | public By get() { 43 | return by; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return by.toString(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/CssSelector.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | 8 | import static org.openqa.selenium.By.cssSelector; 9 | 10 | /** 11 | * This enum is a Supplier of ByCssSelector from Selenium By API. 12 | */ 13 | public enum CssSelector implements Supplier { 14 | 15 | UPDATE("input[value='Update']"), 16 | CONTINUE("input[value='Continue']"), 17 | NEED_CONIRM("input[value='Need Confirm']"), 18 | SUBMIT("input[type='Submit']"); 19 | 20 | private final By by; 21 | 22 | CssSelector(String id) { 23 | this.by = cssSelector(id); 24 | } 25 | 26 | /** 27 | * @return the by instance variable which is a ByCssSelector. 28 | */ 29 | @Override 30 | public By get() { 31 | return by; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return by.toString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/Id.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | import org.openqa.selenium.By; 4 | 5 | import java.util.function.Supplier; 6 | 7 | import static org.openqa.selenium.By.id; 8 | 9 | /** 10 | * This enum is a Supplier of ById from Selenium By API. 11 | */ 12 | public enum Id implements Supplier { 13 | 14 | LOCATION("location"), 15 | MAIN("main"), 16 | MAIN_NAV("main-nav"), 17 | MAIN_LEANDER_BOARD("mainLeaderboard"), 18 | SECONDARY_NAV("secondary-nav"), 19 | GLOBAL_NAV("global-nav"), 20 | UI_DATEPICKER_DIV("ui-datepicker-div"), 21 | CONTENT("content"), 22 | EXTJS_DATEPICKER_TRIGGER("menuitem-1017-textEl"), 23 | EXTJS_CALENDAR("datemenu-1014"), 24 | EXTJS_CALENDAR_MONTH_YEAR("splitbutton-1020-btnInnerEl"), 25 | EXTJS_CALENDAR_PREV_MONTH("datepicker-1015-prevEl"), 26 | EXTJS_CALENDAR_NEXT_MONTH("datepicker-1015-nextEl"), 27 | 28 | DATE_PICKER("datepicker"); 29 | 30 | 31 | private final By by; 32 | 33 | Id(String id) { 34 | this.by = id(id); 35 | } 36 | 37 | /** 38 | * @return the by instance variable which is a ById. 39 | */ 40 | @Override 41 | public By get() { 42 | return by; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return by.toString(); 48 | } 49 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/LinkText.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | import java.util.stream.Stream; 8 | 9 | import static org.openqa.selenium.By.linkText; 10 | 11 | /** 12 | * This enum is a Supplier of ByLinkText from Selenium By API. 13 | */ 14 | public enum LinkText implements Supplier { 15 | 16 | DISCOVER_MORE_EVENT("Discover More Events"), 17 | CANADA("CANADA"), 18 | ALL_CANADA("All Canada"), 19 | CHANGE_LOCATION("change location"), 20 | ACTIVE_MQ_IN_ACTION("ActiveMQ in Action"), 21 | 22 | EXTJS_DATEPICKER_TRIGGER("choose a date"), 23 | 24 | JAVA("Java"), 25 | ONTARIO("Ontario"); 26 | 27 | private final By by; 28 | private final String text; 29 | 30 | LinkText(String text) { 31 | this.by = linkText(text); 32 | this.text = text; 33 | } 34 | 35 | /** 36 | * @return the by instance variable which is a ByLinkText. 37 | */ 38 | @Override 39 | public By get() { 40 | return by; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return by.toString(); 46 | } 47 | 48 | public static LinkText resolve(String text) { 49 | return Stream.of(values()).filter( (LinkText t) -> t.text.equals(text)).findFirst().get(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/Name.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | import org.openqa.selenium.By; 4 | 5 | import java.util.function.Supplier; 6 | 7 | /** 8 | * This enum is a Supplier of ByName from Selenium By API. 9 | */ 10 | public enum Name implements Supplier { 11 | 12 | FILTER_EVENT("filter-events"), 13 | FILE("file"), 14 | Q("q"), 15 | MAILING_OPTION("customFieldDS.customfield_ROW0_value"), 16 | QUANTITY("cartDS.shoppingcart_ROW0_m_orderItemVector_ROW0_m_quantity"); 17 | 18 | private final By by; 19 | 20 | Name(String id) { 21 | this.by = By.name(id); 22 | } 23 | 24 | /** 25 | * @return the by instance variable which is a ByName. 26 | */ 27 | @Override 28 | public By get() { 29 | return by; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return by.toString(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/PartialLinkText.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | 8 | import static org.openqa.selenium.By.partialLinkText; 9 | 10 | /** 11 | * This enum is a Supplier of ByPartialLinkText from Selenium By API. 12 | */ 13 | public enum PartialLinkText implements Supplier { 14 | 15 | UI_DATEPICKER_CLOSE("ui-datepicker-close"); 16 | 17 | private final By by; 18 | 19 | PartialLinkText(String id) { 20 | this.by = partialLinkText(id); 21 | } 22 | 23 | /** 24 | * @return the by instance variable which is a ByPartialLinkText. 25 | */ 26 | @Override 27 | public By get() { 28 | return by; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return by.toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/TagName.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | 8 | import static org.openqa.selenium.By.tagName; 9 | 10 | /** 11 | * This enum is the Supplier of ByTagName from Selenium By API. 12 | */ 13 | public enum TagName implements Supplier { 14 | A("a"), 15 | EM("em"), 16 | H1("h1"), 17 | H5("h5"), 18 | I("i"), 19 | P("p"), 20 | DIV("div"), 21 | IMG("img"), 22 | INPUT("input"), 23 | LI("li"), 24 | OPTION("option"), 25 | SPAN("span"), 26 | STRONG("strong"), 27 | TABLE("table"), 28 | TD("td"), 29 | TR("tr"), 30 | TH("th"), 31 | UL("ul"); 32 | 33 | private final By by; 34 | 35 | TagName(String id) { 36 | this.by = tagName(id); 37 | } 38 | 39 | /** 40 | * @return the by instance variable which is a ByTagName. 41 | */ 42 | @Override 43 | public By get() { 44 | return by; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return by.toString(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selectors/Xpath.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selectors; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | import java.util.function.Supplier; 7 | 8 | import static org.openqa.selenium.By.xpath; 9 | 10 | /** 11 | * This enum is a Supplier ByXpath from Selenium By API. 12 | */ 13 | public enum Xpath implements Supplier { 14 | PARENT(".."), 15 | DIV_CONTAINER_ID("//div[@id='container']"), 16 | LOCATION("//div[@class='tools']/descendant::strong"), 17 | //*[@id="sbse0"]/div[2] 18 | GOOGLE_AUTOCOMPLETE("//*[@id='sbse0']/descendant::div"), 19 | QUANTITY("//div[@id='ys_cartInfo']/descendant::input[@name='cartDS.shoppingcart_ROW0_m_orderItemVector_ROW0_m_quantity']"), 20 | SEARCH_BUTTON("//*[@id=\"desktop-search-form\"]/div/div/span/button"), 21 | CART_BUTTON("//*[@id=\"primary-navbar\"]/ul[2]/li[2]/a"), 22 | TABLE_CONTAINER("//*[@id=\"main\"]"); 23 | 24 | private final By by; 25 | 26 | Xpath(String id) { 27 | this.by = xpath(id); 28 | } 29 | 30 | /** 31 | * @return the by instance variable which is a ByXpath. 32 | */ 33 | @Override 34 | public By get() { 35 | return by; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return by.toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/Actionable.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.TakesScreenshot; 6 | import org.openqa.selenium.UnhandledAlertException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.interactions.Actions; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.util.Date; 13 | 14 | import static org.apache.commons.io.FileUtils.copyFile; 15 | import static org.openqa.selenium.OutputType.FILE; 16 | 17 | public interface Actionable extends WebDriver, 18 | CachedWebDriverSupplier { 19 | 20 | default void accept() { 21 | try { 22 | switchTo().alert().accept(); 23 | } catch (Exception e) { 24 | logger.info("Failed to click OK", e); 25 | } 26 | } 27 | 28 | default void cancel() { 29 | try { 30 | switchTo().alert().dismiss(); 31 | } catch (Exception e) { 32 | logger.info("Failed to click Cancel", e); 33 | } 34 | } 35 | 36 | default void frame(int i) { 37 | switchTo().frame(i); 38 | } 39 | 40 | default void defaultContent() { 41 | switchTo().defaultContent(); 42 | } 43 | 44 | default void mouseOver(Element element) { 45 | new Actions(get()).moveToElement(element).perform(); 46 | } 47 | 48 | default void dragAndDrop(By from, By to) { 49 | new Actions(get()).dragAndDrop(findElement(from), findElement(to)).perform(); 50 | } 51 | 52 | default void save(String title) { 53 | T driver = get(); 54 | if (driver instanceof TakesScreenshot) { 55 | logger.info("Saving screenshot [title={}]", title); 56 | File scrFile = null; 57 | try { 58 | TakesScreenshot camera = (TakesScreenshot) driver; 59 | scrFile = camera.getScreenshotAs(FILE); 60 | copyFile(scrFile, new File("target/screenshots/" + title + new Date().getTime() + ".png")); 61 | scrFile.delete(); 62 | } catch (UnhandledAlertException e) { 63 | logger.info("Failed to copy screenshot.", e); 64 | } catch (IOException e) { 65 | try { 66 | copyFile(scrFile, new File("target/screenshots/" + new Date().getTime() + ".png")); 67 | } catch (IOException e1) { 68 | logger.info("Failed to copy screenshot.", e1); 69 | } 70 | } 71 | } else { 72 | logger.info("Taking screenshot is not supported"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/CachedWebDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | import com.algocrafts.objectcache.SelfPopulatingCache; 4 | import org.openqa.selenium.WebDriver; 5 | import org.slf4j.Logger; 6 | 7 | import java.util.function.Supplier; 8 | 9 | import static org.slf4j.LoggerFactory.getLogger; 10 | 11 | public interface CachedWebDriverSupplier extends Supplier { 12 | 13 | SelfPopulatingCache, ? extends WebDriver> store 14 | = SelfPopulatingCache.create((CachedWebDriverSupplier supplier) -> supplier.init()); 15 | 16 | Logger logger = getLogger(CachedWebDriverSupplier.class); 17 | 18 | T init(); 19 | 20 | @SuppressWarnings("unchecked") 21 | default T get() { 22 | return (T) store.valueOf(this); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/Clickable.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | public interface Clickable { 4 | 5 | void click(); 6 | 7 | } -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/ElementFinder.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.SearchContext; 5 | import org.openqa.selenium.WebElement; 6 | import org.slf4j.Logger; 7 | 8 | import static org.slf4j.LoggerFactory.getLogger; 9 | 10 | public class ElementFinder implements Locator { 11 | 12 | public static final Logger logger = getLogger(ElementFinder.class); 13 | 14 | private final By by; 15 | 16 | public ElementFinder(By by) { 17 | this.by = by; 18 | } 19 | 20 | @Override 21 | public Element locate(SearchContext t) { 22 | logger.info("Seeking [{}]", by); 23 | WebElement element = by.findElement(t); 24 | logger.info("Found [{}]", element); 25 | Element element1 = element instanceof Element ? (Element) element : new Element(element); 26 | element1.setBy(by); 27 | element1.setBrowser(t); 28 | return element1; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/ElementsFinder.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.SearchContext; 5 | import org.openqa.selenium.WebElement; 6 | import org.slf4j.Logger; 7 | 8 | import java.util.List; 9 | 10 | import static java.util.stream.Collectors.toList; 11 | import static org.slf4j.LoggerFactory.getLogger; 12 | 13 | 14 | public class ElementsFinder implements Locator>{ 15 | public static final Logger logger = getLogger(ElementsFinder.class); 16 | private By by; 17 | 18 | public ElementsFinder(By by) { 19 | this.by = by; 20 | } 21 | 22 | @Override 23 | public List locate(SearchContext t) { 24 | logger.info("Seeking elements [{}]", by); 25 | List elements = t.findElements(by); 26 | logger.info("Found [{}]", elements); 27 | return elements.stream().map(Element::new).collect(toList()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/selenium/Locating.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.selenium; 2 | 3 | import java.util.function.Predicate; 4 | 5 | public class Locating, T2> { 6 | 7 | private final T1 where; 8 | private final Locator locator; 9 | 10 | /** 11 | * Constructor of the Locating. 12 | * 13 | * @param where where 14 | * @param locator locator 15 | */ 16 | public Locating(T1 where, Locator locator) { 17 | this.where = where; 18 | this.locator = locator; 19 | } 20 | 21 | public T2 locate() { 22 | return locator.locate(where); 23 | } 24 | 25 | public T locate(Locator locator) { 26 | return this.locator.andThen(locator).locate(where); 27 | } 28 | 29 | public T use(Locator locator) { 30 | return locator.locate(where); 31 | } 32 | 33 | public boolean test(Predicate predicate) { 34 | return this.locator.and(predicate).test(where); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return locator.toString(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/table/Table.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.table; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.selenium.Element; 6 | import com.algocrafts.selenium.Locator; 7 | import com.algocrafts.selenium.SearchScope; 8 | 9 | import java.util.stream.Collectors; 10 | import java.util.stream.Stream; 11 | 12 | import static com.algocrafts.converters.GetText.TEXT; 13 | import static com.algocrafts.locators.Locators.elements; 14 | import static com.algocrafts.selectors.TagName.*; 15 | import static java.util.stream.Collectors.toSet; 16 | 17 | public class Table> { 18 | 19 | 20 | private final Where where; 21 | private final Locator locator; 22 | private final Locator, T> mapper; 23 | 24 | public Table(Where where, 25 | Locator locator, 26 | Locator, T> mapper) { 27 | this.where = where; 28 | this.locator = locator; 29 | this.mapper = mapper; 30 | } 31 | 32 | public Stream getHeader() { 33 | return locator.andThen(elements(TH)).locate(where).map(TEXT); 34 | } 35 | 36 | public Stream getRows() { 37 | return locator.andThen(elements(TR)).locate(where) 38 | .filter(e -> 39 | Locators.optionalElement(TD) 40 | .locate(e) 41 | .isPresent()) 42 | .map(elements(TD)) 43 | .map(mapper); 44 | } 45 | 46 | public TableContents getContents() { 47 | return new TableContents( 48 | this.getHeader().collect(toSet()), 49 | this.getRows().collect(Collectors.toSet()) 50 | ); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/main/java/com/algocrafts/table/TableContents.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.table; 2 | 3 | 4 | import com.algocrafts.domain.SetDiff; 5 | 6 | import java.util.Set; 7 | 8 | public class TableContents { 9 | 10 | private final Set headers; 11 | private final Set rows; 12 | private SetDiff diff; 13 | 14 | public TableContents(Set headers, Set rows) { 15 | this.headers = headers; 16 | this.rows = rows; 17 | } 18 | 19 | @Override 20 | @SuppressWarnings("unchecked") 21 | public boolean equals(Object other) { 22 | if (other instanceof TableContents) { 23 | TableContents actual = (TableContents) other; 24 | 25 | if (!headers.equals(actual.headers)) { 26 | diff = new SetDiff<>("headers are different,", 27 | headers, 28 | actual.headers); 29 | return false; 30 | } else { 31 | if (!this.rows.equals(actual.rows)) { 32 | diff = new SetDiff<>("rows are different,", 33 | this.rows, 34 | actual.rows); 35 | return false; 36 | } 37 | return true; 38 | } 39 | } else { 40 | diff = new SetDiff<>("not a TableContents,", headers, null); 41 | return false; 42 | } 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return diff.toString(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/BillingAddressForm.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | import com.algocrafts.domain.Countries; 4 | import com.algocrafts.domain.UnitedStates; 5 | import com.algocrafts.pages.Page; 6 | import com.bookstore.domain.Address; 7 | 8 | import static com.bookstore.BookStoreId.*; 9 | 10 | public class BillingAddressForm { 11 | private Page page; 12 | 13 | public BillingAddressForm(Page page) { 14 | this.page = page; 15 | } 16 | 17 | public void setBillingAddress(Address address) { 18 | page.put(BILLING_FIRST_NAME, address.firstName); 19 | page.put(BILLING_LAST_NAME, address.lastName); 20 | page.put(BILLING_ADDRESS1, address.street1); 21 | page.put(BILLING_ADDRESS2, address.street2); 22 | page.put(BILLING_CITY, address.city); 23 | page.put(BILLING_STATE, address.state); 24 | page.put(BILLING_ZIP, address.zipcode); 25 | page.select(BILLING_COUNTRY, address.country); 26 | } 27 | 28 | public Address getBillingAddress() { 29 | return new Address( 30 | page.get(BILLING_ADDRESS1), 31 | page.get(BILLING_ADDRESS2), 32 | page.get(BILLING_CITY), 33 | page.get(BILLING_ZIP), 34 | page.get(BILLING_STATE, UnitedStates::fromString), 35 | page.get(BILLING_COUNTRY, Countries::fromString), 36 | page.get(BILLING_FIRST_NAME), 37 | page.get(BILLING_LAST_NAME)); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/BookPage.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selectors.TagName; 6 | import com.algocrafts.selenium.Element; 7 | import com.google.common.base.Predicate; 8 | import org.openqa.selenium.support.ui.FluentWait; 9 | 10 | import static com.algocrafts.selectors.Xpath.CART_BUTTON; 11 | 12 | public class BookPage extends Page { 13 | 14 | private Predicate colorBecomeWhite = (BookPage b) -> cartButton().getCssValue("color").equals("rgba(255, 255, 255, 1)"); 15 | 16 | public BookPage(Page page) { 17 | super(page); 18 | } 19 | 20 | public void addToCart() { 21 | findElements(TagName.INPUT).filter((e) -> e.getAttribute("value").equals("add to cart")).findFirst().get().click(); 22 | new FluentWait<>(this).until(colorBecomeWhite) ; 23 | } 24 | 25 | public void secondAddToCart() { 26 | ((Element) findElements(TagName.INPUT).filter((e) -> e.getAttribute("value").equals("add to cart")).toArray()[1]).click(); 27 | new FluentWait<>(this).until(colorBecomeWhite); 28 | } 29 | 30 | public void gotoCart() { 31 | cartButton().click(); 32 | } 33 | 34 | public Element cartButton() { 35 | return untilFound(CART_BUTTON); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/BookStoreId.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | import org.openqa.selenium.By; 4 | 5 | import java.util.function.Supplier; 6 | 7 | import static org.openqa.selenium.By.id; 8 | 9 | public enum BookStoreId implements Supplier { 10 | 11 | SHIPPING_FIRST_NAME("shipping-first-name"), 12 | SHIPPING_LAST_NAME("shipping-last-name"), 13 | SHIPPING_ADDRESS1("shipping-address1"), 14 | SHIPPING_ADDRESS2("shipping-address2"), 15 | SHIPPING_CITY("shipping-city"), 16 | SHIPPING_STATE("shipping-state"), 17 | SHIPPING_COUNTRY("shipping-country"), 18 | SHIPPING_ZIP("shipping-zip"), 19 | SHIPPING_EMAIL("shipping-email"), 20 | 21 | 22 | BILLING_FIRST_NAME("billing-first-name"), 23 | BILLING_LAST_NAME("billing-last-name"), 24 | BILLING_ADDRESS1("billing-address1"), 25 | BILLING_ADDRESS2("billing-address2"), 26 | BILLING_CITY("billing-city"), 27 | BILLING_STATE("billing-state"), 28 | BILLING_COUNTRY("billing-country"), 29 | BILLING_ZIP("billing-zip"), 30 | BILLING_EMAIL("billing-email"), 31 | 32 | CARD_TYPE("card-type"), 33 | CARD_NUMBER("card-number"), 34 | CARD_CVV("card-cvv"), 35 | CARD_EXP_MONTH("card-exp-month"), 36 | CARD_EXP_YEAR("card-exp-year"), 37 | 38 | COUPON_CODE("gc-redemption-code"), 39 | SEARCH_INPUT("navbar-search"), 40 | RATINGS("ratings"), 41 | CONFIRM_EMAIL("confirm-email"), 42 | 43 | COMMENTS("comments"), 44 | ERROR_MESSAGES("ys_errorMessages"), 45 | 46 | SHOPPING_CART("ys_cart"), 47 | YAHOO_COPYRIGHT("ys_copyright"), 48 | CONTENT("content"), 49 | FOOTER("footer"); 50 | 51 | private final By by; 52 | 53 | BookStoreId(String id) { 54 | this.by = id(id); 55 | } 56 | 57 | @Override 58 | public By get() { 59 | return by; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return by.toString(); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/com/bookstore/BookstoreHomePage.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | 4 | import com.algocrafts.browsers.Browsers; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selectors.Xpath; 7 | import com.algocrafts.selenium.Clickable; 8 | import org.openqa.selenium.By; 9 | 10 | import static com.algocrafts.selectors.Xpath.SEARCH_BUTTON; 11 | import static com.bookstore.BookStoreId.SEARCH_INPUT; 12 | 13 | public class BookstoreHomePage extends Page { 14 | 15 | public BookstoreHomePage(Browsers browser, Clickable url) { 16 | super(browser, url); 17 | } 18 | 19 | public void searchBook(String bookname) { 20 | put(SEARCH_INPUT, bookname); 21 | untilFound(SEARCH_BUTTON).click(); 22 | untilFound(() -> By.partialLinkText(bookname)).click(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/CreditCardForm.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | 4 | import com.algocrafts.domain.CreditCardType; 5 | import com.algocrafts.pages.Page; 6 | import com.bookstore.domain.CreditCard; 7 | 8 | import java.time.Month; 9 | 10 | import static com.algocrafts.converters.StringToInt.PARSE_INT; 11 | import static com.bookstore.BookStoreId.*; 12 | 13 | public class CreditCardForm { 14 | 15 | private Page page; 16 | 17 | public CreditCardForm(Page page) { 18 | this.page = page; 19 | } 20 | 21 | public void setCreditCard(CreditCard card) { 22 | page.put(CARD_CVV, card.cardCvv); 23 | page.put(CARD_NUMBER, card.cardNumber); 24 | page.select(CARD_TYPE, card.cardType); 25 | page.select(CARD_EXP_MONTH, card.expirationMonth); 26 | page.select(CARD_EXP_YEAR, card.expirationYear); 27 | } 28 | 29 | public CreditCard getCreditCard() { 30 | return new CreditCard( 31 | page.get(CARD_TYPE, CreditCardType::fromString), 32 | page.get(CARD_NUMBER), 33 | page.get(CARD_CVV), 34 | page.get(CARD_EXP_MONTH, Month::valueOf), 35 | page.get(CARD_EXP_YEAR, PARSE_INT)); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/OtherInformationForm.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.bookstore.domain.MailingOptions; 6 | import com.bookstore.domain.OtherInformation; 7 | 8 | import static com.algocrafts.selectors.Name.MAILING_OPTION; 9 | import static com.bookstore.BookStoreId.*; 10 | 11 | public class OtherInformationForm { 12 | 13 | private Page page; 14 | 15 | public OtherInformationForm(Page page) { 16 | this.page = page; 17 | } 18 | 19 | public void setOtherInformation(OtherInformation info) { 20 | page.put(COUPON_CODE, info.couponCode); 21 | page.put(BILLING_EMAIL, info.emailAddress); 22 | page.put(COMMENTS, info.comments); 23 | page.setCheckbox(CONFIRM_EMAIL, info.confirmEmail); 24 | page.setCheckbox(RATINGS, info.askRating); 25 | page.setRadioButton(MAILING_OPTION, info.mailingOptions); 26 | } 27 | 28 | public OtherInformation getOtherInformation() { 29 | return new OtherInformation( 30 | page.get(COUPON_CODE), 31 | page.get(BILLING_EMAIL), 32 | page.isChecked(CONFIRM_EMAIL), 33 | page.isChecked(RATINGS), 34 | page.get(MAILING_OPTION, MailingOptions::from), 35 | page.get(COMMENTS) 36 | ); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/ShippingAddressForm.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | import com.algocrafts.domain.Countries; 4 | import com.algocrafts.domain.UnitedStates; 5 | import com.algocrafts.pages.Page; 6 | import com.bookstore.domain.Address; 7 | 8 | import static com.bookstore.BookStoreId.*; 9 | 10 | public class ShippingAddressForm { 11 | private Page page; 12 | 13 | public ShippingAddressForm(Page page) { 14 | this.page = page; 15 | } 16 | 17 | public void setShippingAddress(Address address) { 18 | page.put(SHIPPING_FIRST_NAME, address.firstName); 19 | page.put(SHIPPING_LAST_NAME, address.lastName); 20 | page.put(SHIPPING_ADDRESS1, address.street1); 21 | page.put(SHIPPING_ADDRESS2, address.street2); 22 | page.put(SHIPPING_CITY, address.city); 23 | page.put(SHIPPING_STATE, address.state); 24 | page.put(SHIPPING_ZIP, address.zipcode); 25 | page.select(SHIPPING_COUNTRY, address.country); 26 | } 27 | 28 | public Address getShippingAddress() { 29 | return new Address( 30 | page.get(SHIPPING_ADDRESS1), 31 | page.get(SHIPPING_ADDRESS2), 32 | page.get(SHIPPING_CITY), 33 | page.get(SHIPPING_ZIP), 34 | page.get(SHIPPING_STATE, UnitedStates::fromString), 35 | page.get(SHIPPING_COUNTRY, Countries::fromString), 36 | page.get(SHIPPING_FIRST_NAME), 37 | page.get(SHIPPING_LAST_NAME)); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/ShoppingCartPage.java: -------------------------------------------------------------------------------- 1 | package com.bookstore; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selectors.Xpath; 6 | import com.bookstore.domain.Address; 7 | import com.bookstore.domain.CreditCard; 8 | import com.bookstore.domain.ErrorMessages; 9 | import com.bookstore.domain.OtherInformation; 10 | 11 | import static com.algocrafts.selectors.CssSelector.CONTINUE; 12 | import static com.algocrafts.selectors.CssSelector.UPDATE; 13 | 14 | public class ShoppingCartPage extends Page { 15 | 16 | private final BillingAddressForm billingAddressForm = new BillingAddressForm(this); 17 | private final CreditCardForm creditCardForm = new CreditCardForm(this); 18 | private final OtherInformationForm otherInformationForm = new OtherInformationForm(this); 19 | private final ShippingAddressForm shippingAddressForm = new ShippingAddressForm(this); 20 | 21 | public ShoppingCartPage(Page page) { 22 | super(page); 23 | } 24 | 25 | public void setBillingAddress(Address address) { 26 | billingAddressForm.setBillingAddress(address); 27 | } 28 | 29 | public void getBillingAddress() { 30 | billingAddressForm.getBillingAddress(); 31 | } 32 | 33 | public void setCreditCard(CreditCard card) { 34 | creditCardForm.setCreditCard(card); 35 | } 36 | 37 | public CreditCard getCreditCard() { 38 | return creditCardForm.getCreditCard(); 39 | } 40 | 41 | public void setQuantity(int quantity) { 42 | put(Xpath.QUANTITY, quantity); 43 | button(UPDATE).click(); 44 | } 45 | 46 | public void setOtherInformation(OtherInformation info) { 47 | otherInformationForm.setOtherInformation(info); 48 | } 49 | 50 | public OtherInformation getOtherInformation() { 51 | return otherInformationForm.getOtherInformation(); 52 | } 53 | 54 | public void continues() { 55 | button(CONTINUE).click(); 56 | } 57 | 58 | public ErrorMessages getErrorMessages() { 59 | return new ErrorMessages(this); 60 | } 61 | 62 | public void setShippingAddress(Address shippingAddress) { 63 | shippingAddressForm.setShippingAddress(shippingAddress); 64 | } 65 | 66 | public void getShippingAddress() { 67 | shippingAddressForm.getShippingAddress(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/domain/Address.java: -------------------------------------------------------------------------------- 1 | package com.bookstore.domain; 2 | 3 | import com.algocrafts.domain.Countries; 4 | import com.algocrafts.domain.UnitedStates; 5 | 6 | public class Address { 7 | public final String firstName; 8 | public final String lastName; 9 | public final String street1; 10 | public final String street2; 11 | public final String city; 12 | public final UnitedStates state; 13 | public final String zipcode; 14 | public final Countries country; 15 | 16 | public Address(String street1, 17 | String street2, 18 | String city, 19 | String zipcode, 20 | UnitedStates state, 21 | Countries country, 22 | String firstName, 23 | String lastName) { 24 | this.street1 = street1; 25 | this.street2 = street2; 26 | this.city = city; 27 | this.zipcode = zipcode; 28 | this.state = state; 29 | this.country = country; 30 | this.firstName = firstName; 31 | this.lastName = lastName; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/domain/CreditCard.java: -------------------------------------------------------------------------------- 1 | package com.bookstore.domain; 2 | 3 | import com.algocrafts.domain.CreditCardType; 4 | 5 | import java.time.Month; 6 | 7 | public class CreditCard { 8 | 9 | public final String cardNumber; 10 | public final String cardCvv; 11 | public final String expirationMonth; 12 | public final int expirationYear; 13 | public final CreditCardType cardType; 14 | 15 | public CreditCard(CreditCardType cardType, 16 | String cardNumber, 17 | String cardCvv, 18 | Month expirationMonth, 19 | int expirationYear) { 20 | this.cardType = cardType; 21 | this.cardNumber = cardNumber; 22 | this.cardCvv = cardCvv; 23 | this.expirationMonth = expirationMonth.toString().charAt(0) + 24 | expirationMonth.toString().substring(1, 3).toLowerCase() + 25 | " (" + (expirationMonth.ordinal() + 1) + ")"; 26 | this.expirationYear = expirationYear; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/domain/ErrorMessages.java: -------------------------------------------------------------------------------- 1 | package com.bookstore.domain; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.locators.Locators; 6 | 7 | import java.util.List; 8 | import java.util.stream.Stream; 9 | 10 | import static com.algocrafts.converters.GetText.TEXT; 11 | import static com.algocrafts.locators.Locators.elements; 12 | import static com.algocrafts.selectors.TagName.LI; 13 | import static com.bookstore.BookStoreId.ERROR_MESSAGES; 14 | import static java.util.stream.Collectors.toList; 15 | 16 | public class ErrorMessages { 17 | 18 | private final List errorMessages; 19 | 20 | public ErrorMessages(List errorMessages) { 21 | this.errorMessages = errorMessages; 22 | } 23 | 24 | public ErrorMessages(Stream errorMessages) { 25 | this(errorMessages.collect(toList())); 26 | } 27 | 28 | public ErrorMessages(Page page) { 29 | this(Locators.element(ERROR_MESSAGES) 30 | .andThen(elements(LI)).locate(page).map(TEXT)); 31 | } 32 | 33 | @Override 34 | public boolean equals(Object other) { 35 | return this == other || 36 | (other instanceof ErrorMessages && 37 | ((ErrorMessages) other).errorMessages.equals(this.errorMessages) 38 | ); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return errorMessages.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/domain/MailingOptions.java: -------------------------------------------------------------------------------- 1 | package com.bookstore.domain; 2 | 3 | 4 | import static java.util.stream.Stream.of; 5 | 6 | public enum MailingOptions { 7 | 8 | Weekly_Newsletter( 9 | "Weekly newsletter--New books," + 10 | " updates, news, and special offers"), 11 | Deal_Of_the_Day( 12 | "Deal of the Day--These amazing " + 13 | "special offers last just 24 hours!"), 14 | Both("Both"), 15 | No_Promotional_Mailers( 16 | "No promotional mailers. I will still" + 17 | " receive updates on my MEAPs and other books."), 18 | Keep_Me( 19 | "Keep me on the lists I'm already on."); 20 | 21 | private final String string; 22 | 23 | MailingOptions(String string) { 24 | this.string = string; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return string; 30 | } 31 | 32 | /** 33 | * This method filters the enum constants using the string and returns the first 34 | * matching constant. 35 | * 36 | * @param string the string value 37 | * @return enum with the string value 38 | */ 39 | public static MailingOptions from(String string) { 40 | return of(values()) 41 | .filter( 42 | (o) -> string.equals(o.string)) 43 | .findFirst() 44 | .get(); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/bookstore/domain/OtherInformation.java: -------------------------------------------------------------------------------- 1 | package com.bookstore.domain; 2 | 3 | 4 | public class OtherInformation { 5 | public final String couponCode; 6 | public final String emailAddress; 7 | public final boolean askRating; 8 | public final MailingOptions mailingOptions; 9 | public final boolean confirmEmail; 10 | public final String comments; 11 | 12 | public OtherInformation(String couponCode, 13 | String emailAddress, 14 | boolean confirmaEmail, 15 | boolean askRating, 16 | MailingOptions mailingOptions, 17 | String comments) { 18 | this.couponCode = couponCode; 19 | this.emailAddress = emailAddress; 20 | this.confirmEmail = confirmaEmail; 21 | this.askRating = askRating; 22 | this.mailingOptions = mailingOptions; 23 | this.comments = comments; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/daugherty/AllMenuLocatorForDaugherty.java: -------------------------------------------------------------------------------- 1 | package com.daugherty; 2 | 3 | 4 | import com.algocrafts.clickables.Menu; 5 | import com.algocrafts.conditions.Equals; 6 | import com.algocrafts.converters.Filter; 7 | import com.algocrafts.converters.FirstMatch; 8 | import com.algocrafts.locators.ElementLocator; 9 | import com.algocrafts.pages.Page; 10 | import com.algocrafts.selectors.Id; 11 | import com.algocrafts.selenium.Clickable; 12 | import com.algocrafts.selenium.Element; 13 | import com.algocrafts.selenium.Locator; 14 | import org.openqa.selenium.By; 15 | 16 | import java.util.List; 17 | import java.util.function.Supplier; 18 | import java.util.stream.Stream; 19 | 20 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 21 | import static com.algocrafts.converters.GetText.LINK_TEXT; 22 | import static com.algocrafts.converters.GetText.TEXT; 23 | import static com.algocrafts.converters.OptionalGetter.GET; 24 | import static com.algocrafts.locators.Locators.elements; 25 | import static com.algocrafts.selectors.TagName.LI; 26 | import static com.google.common.collect.Lists.newArrayList; 27 | 28 | public class AllMenuLocatorForDaugherty implements Locator> { 29 | 30 | @Override 31 | public Stream locate(Page page) { 32 | 33 | List allMenu = getClickables(page, Id.MAIN_NAV); 34 | 35 | allMenu.addAll(getClickables(page, Id.SECONDARY_NAV)); 36 | return allMenu.stream(); 37 | } 38 | 39 | private List getClickables(Page page, Supplier id) { 40 | Locator> menubars = new ElementLocator(id) 41 | .andThen(elements(LI)) 42 | .andThen(new Filter<>(DISPLAYED)); 43 | 44 | List allMenu = newArrayList(); 45 | menubars.apply(page).forEach(header -> { 46 | try { 47 | Element menubar = menubars 48 | .andThen(new FirstMatch<>(TEXT.and(new Equals(LINK_TEXT.locate(header))))) 49 | .andThen(GET) 50 | .locate(page); 51 | 52 | String group = LINK_TEXT.apply(menubar); 53 | allMenu.add(new Menu(page, new MenuGroupLocator(group, id))); 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | }); 58 | return allMenu; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/daugherty/DaughertyHomePage.java: -------------------------------------------------------------------------------- 1 | package com.daugherty; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selenium.Browser; 7 | import com.algocrafts.selenium.Clickable; 8 | import com.algocrafts.selenium.Locator; 9 | import org.openqa.selenium.WebDriver; 10 | 11 | import java.util.stream.Stream; 12 | 13 | import static com.algocrafts.converters.GetText.TEXT; 14 | import static com.algocrafts.converters.OptionalGetter.GET; 15 | import static org.openqa.selenium.By.cssSelector; 16 | 17 | public class DaughertyHomePage extends Page { 18 | 19 | final Locator> allMenuLocator; 20 | 21 | public DaughertyHomePage(Browser browser, Clickable url, Locator> allMenuLocator) { 22 | super(browser, url); 23 | this.allMenuLocator = allMenuLocator; 24 | } 25 | 26 | public Stream getAllMenu() { 27 | return allMenuLocator.apply(this); 28 | } 29 | 30 | public String getTitle() { 31 | try { 32 | return Locators.optionalElement(() -> cssSelector("body > header.page-header > div > h1 > span")).andThen(GET).andThen(TEXT).locate(this); 33 | } catch (Exception e) { 34 | return ""; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/daugherty/MenuGroupLocator.java: -------------------------------------------------------------------------------- 1 | package com.daugherty; 2 | 3 | 4 | import com.algocrafts.locators.ElementLocator; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selenium.Element; 7 | import com.algocrafts.selenium.Locator; 8 | import org.openqa.selenium.By; 9 | 10 | import java.util.function.Supplier; 11 | 12 | import static org.openqa.selenium.By.linkText; 13 | 14 | 15 | public class MenuGroupLocator implements Locator { 16 | 17 | private final String headText; 18 | private final Supplier id; 19 | 20 | public MenuGroupLocator(String menuGroup, Supplier id) { 21 | this.headText = menuGroup; 22 | this.id = id; 23 | } 24 | 25 | public Element locate(Page page) { 26 | return new ElementLocator(id) 27 | .andThen(new ElementLocator<>(() -> linkText(headText))).locate(page); 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "[" + headText + "]"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/extjs/CalendarClicker.java: -------------------------------------------------------------------------------- 1 | package com.extjs; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selectors.Id; 7 | import com.algocrafts.selenium.Element; 8 | import com.algocrafts.selenium.Locator; 9 | 10 | import static com.algocrafts.converters.ElementFunctions.CLICK; 11 | import static com.algocrafts.locators.Locators.element; 12 | 13 | public enum CalendarClicker implements Locator { 14 | NEXT_MONTH( 15 | Locators.element(Id.EXTJS_CALENDAR) 16 | .andThen(element(Id.EXTJS_CALENDAR_NEXT_MONTH)) 17 | ), 18 | PREVIOUS_MONTH( 19 | Locators.element(Id.EXTJS_CALENDAR) 20 | .andThen(element(Id.EXTJS_CALENDAR_PREV_MONTH)) 21 | ); 22 | 23 | private final Locator locator; 24 | 25 | CalendarClicker(Locator locator) { 26 | this.locator = locator; 27 | } 28 | 29 | @Override 30 | public Void locate(Page page) { 31 | return locator.andThen(CLICK).locate(page); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/extjs/CalendarIntegerLocator.java: -------------------------------------------------------------------------------- 1 | package com.extjs; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selenium.Locator; 7 | 8 | import static com.algocrafts.converters.GetText.TEXT; 9 | import static com.algocrafts.converters.Ordinal.ORDINAL; 10 | import static com.algocrafts.converters.StringConverter.FIRST_HALF; 11 | import static com.algocrafts.converters.StringConverter.SECOND_HALF; 12 | import static com.algocrafts.converters.StringToInt.PARSE_INT; 13 | import static com.algocrafts.converters.StringToMonth.TO_MONTH; 14 | import static com.algocrafts.locators.Locators.element; 15 | import static com.algocrafts.selectors.Id.EXTJS_CALENDAR; 16 | import static com.algocrafts.selectors.Id.EXTJS_CALENDAR_MONTH_YEAR; 17 | 18 | public enum CalendarIntegerLocator implements Locator { 19 | 20 | /** 21 | * Locate the integer value representing displayed year on a calendar 22 | */ 23 | DISPLAYED_YEAR( 24 | Locators.element(EXTJS_CALENDAR) 25 | .andThen(element(EXTJS_CALENDAR_MONTH_YEAR)) 26 | .andThen(TEXT) 27 | .andThen(SECOND_HALF) 28 | .andThen(PARSE_INT) 29 | ), 30 | 31 | /** 32 | * Locate the integer value representing displayed month on a calendar 33 | */ 34 | DISPLAYED_MONTH( 35 | Locators.element(EXTJS_CALENDAR) 36 | .andThen(element(EXTJS_CALENDAR_MONTH_YEAR)) 37 | .andThen(TEXT) 38 | .andThen(FIRST_HALF) 39 | .andThen(TO_MONTH) 40 | .andThen(ORDINAL) 41 | ); 42 | 43 | private final Locator locator; 44 | 45 | CalendarIntegerLocator(Locator locator) { 46 | this.locator = locator; 47 | } 48 | 49 | @Override 50 | public Integer locate(Page page) { 51 | return locator.locate(page); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/extjs/TriggerHover.java: -------------------------------------------------------------------------------- 1 | package com.extjs; 2 | 3 | 4 | import com.algocrafts.converters.FrameLocator; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.pages.Page; 7 | import com.algocrafts.selenium.Element; 8 | import com.algocrafts.selenium.Locator; 9 | 10 | import static com.algocrafts.selectors.LinkText.EXTJS_DATEPICKER_TRIGGER; 11 | 12 | public enum TriggerHover implements Locator { 13 | TRIGGER( 14 | new FrameLocator(1).andThen(Locators.element(EXTJS_DATEPICKER_TRIGGER)) 15 | ); 16 | 17 | private final Locator locator; 18 | 19 | TriggerHover(Locator locator) { 20 | this.locator = locator; 21 | } 22 | 23 | @Override 24 | public Void locate(Page page) { 25 | locator.andThen(page.mouseOver()).locate(page); 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/google/GooglePage.java: -------------------------------------------------------------------------------- 1 | package com.google; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Browser; 5 | import com.algocrafts.selenium.Clickable; 6 | 7 | import static com.algocrafts.locators.Locators.elements; 8 | import static com.algocrafts.selectors.Name.Q; 9 | import static com.algocrafts.selectors.Xpath.GOOGLE_AUTOCOMPLETE; 10 | 11 | public class GooglePage extends Page { 12 | public GooglePage(Browser browser, Clickable clickable) { 13 | super(browser, clickable); 14 | } 15 | 16 | public void autocomplete(String input) { 17 | autocomplete(Q, input, elements(GOOGLE_AUTOCOMPLETE)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/JQueryHomePage.java: -------------------------------------------------------------------------------- 1 | package com.jquery; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selenium.Browser; 6 | import com.algocrafts.selenium.Clickable; 7 | import com.algocrafts.selenium.Locator; 8 | import org.openqa.selenium.WebDriver; 9 | 10 | import java.util.stream.Stream; 11 | 12 | public class JQueryHomePage extends Page { 13 | 14 | private final Locator> allMenuLocator; 15 | 16 | public JQueryHomePage(Browser browser, 17 | Clickable url, 18 | Locator> allMenuLocator) { 19 | super(browser, url); 20 | this.allMenuLocator = allMenuLocator; 21 | } 22 | 23 | public Stream getAllMenu() { 24 | return allMenuLocator.locate(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/datepicker/JQueryDatePickerPage.java: -------------------------------------------------------------------------------- 1 | package com.jquery.datepicker; 2 | 3 | 4 | import com.algocrafts.clickables.Url; 5 | import com.algocrafts.datepicker.CalendarPicker; 6 | import com.algocrafts.datepicker.Datepicker; 7 | import com.algocrafts.locators.ElementLocator; 8 | import com.algocrafts.pages.Page; 9 | import com.algocrafts.selenium.Browser; 10 | import com.jquery.datepicker.locators.JQueryDayPicker; 11 | 12 | import java.time.Month; 13 | 14 | import static com.algocrafts.conditions.PagePredicates.JQUERY_CALENDAR_NOT_DISPLAYED; 15 | import static com.algocrafts.converters.GetText.VALUE; 16 | import static com.algocrafts.selectors.Id.DATE_PICKER; 17 | import static com.jquery.datepicker.locators.CalendarClicker.*; 18 | import static com.jquery.datepicker.locators.CalendarIntegerLocator.DISPLAYED_MONTH; 19 | import static com.jquery.datepicker.locators.CalendarIntegerLocator.DISPLAYED_YEAR; 20 | 21 | public class JQueryDatePickerPage extends Page { 22 | 23 | public JQueryDatePickerPage(Browser browser) { 24 | super(browser, new Url<>(browser, "http://jqueryui.com/datepicker/")); 25 | } 26 | 27 | private final Datepicker datepicker = new Datepicker(this, 28 | TRIGGER, 29 | new CalendarPicker(this, PREVIOUS_YEAR, NEXT_YEAR, DISPLAYED_YEAR), 30 | new CalendarPicker(this, PREVIOUS_MONTH, NEXT_MONTH, DISPLAYED_MONTH), 31 | new JQueryDayPicker(this, JQUERY_CALENDAR_NOT_DISPLAYED) 32 | ); 33 | 34 | public void pick(Month month, int day, int year) { 35 | datepicker.pick(month, day, year); 36 | } 37 | 38 | public String getDate() { 39 | return new ElementLocator(DATE_PICKER) 40 | .andThen(VALUE) 41 | .locate(this); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/datepicker/locators/CalendarClicker.java: -------------------------------------------------------------------------------- 1 | package com.jquery.datepicker.locators; 2 | 3 | 4 | import com.algocrafts.converters.FrameLocator; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.pages.Page; 7 | import com.algocrafts.selenium.Locator; 8 | 9 | import static com.algocrafts.converters.ElementFunctions.CLICK; 10 | import static com.algocrafts.locators.Locators.element; 11 | import static com.algocrafts.selectors.ClassName.*; 12 | import static com.algocrafts.selectors.Id.DATE_PICKER; 13 | import static com.algocrafts.selectors.Id.UI_DATEPICKER_DIV; 14 | 15 | public enum CalendarClicker implements Locator { 16 | TRIGGER( 17 | new FrameLocator(0) 18 | .andThen(element(DATE_PICKER)).andThen(CLICK) 19 | ), 20 | NEXT_MONTH( 21 | Locators.element(UI_DATEPICKER_DIV) 22 | .andThen(element(UI_DATEPICKER_NEXT)).andThen(CLICK) 23 | ), 24 | PREVIOUS_MONTH( 25 | Locators.element(UI_DATEPICKER_DIV) 26 | .andThen(element(UI_DATEPICKER_PREV)).andThen(CLICK) 27 | ), 28 | NEXT_YEAR ( 29 | (Page browser) -> { 30 | for (int i = 0; i < 12; i++) { 31 | NEXT_MONTH.locate(browser); 32 | } 33 | return null; 34 | } 35 | ), 36 | PREVIOUS_YEAR ( 37 | (Page browser) -> { 38 | for (int i = 0; i < 12; i++) { 39 | PREVIOUS_MONTH.locate(browser); 40 | } 41 | return null; 42 | } 43 | ), 44 | CLOSE_BUTTON( 45 | Locators.element(UI_DATEPICKER_DIV) 46 | .andThen(element(UI_DATEPICKER_CLOSE)).andThen(CLICK) 47 | ); 48 | 49 | private final Locator locator; 50 | 51 | CalendarClicker(Locator locator) { 52 | this.locator = locator; 53 | } 54 | 55 | @Override 56 | public Void locate(Page page) { 57 | return locator.locate(page); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/datepicker/locators/CalendarIntegerLocator.java: -------------------------------------------------------------------------------- 1 | package com.jquery.datepicker.locators; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.pages.Page; 6 | import com.algocrafts.selenium.Element; 7 | import com.algocrafts.selenium.Locator; 8 | 9 | import static com.algocrafts.converters.GetText.TEXT; 10 | import static com.algocrafts.converters.Ordinal.ORDINAL; 11 | import static com.algocrafts.converters.StringToInt.PARSE_INT; 12 | import static com.algocrafts.converters.StringToMonth.TO_MONTH; 13 | import static com.algocrafts.locators.Locators.element; 14 | import static com.algocrafts.selectors.ClassName.*; 15 | import static com.algocrafts.selectors.Id.UI_DATEPICKER_DIV; 16 | 17 | public enum CalendarIntegerLocator implements Locator { 18 | 19 | /** 20 | * Locate the integer value representing displayed year on a calendar 21 | */ 22 | DISPLAYED_YEAR( 23 | Locators.element(UI_DATEPICKER_DIV) 24 | .andThen(element(UI_DATEPICKER_YEAR)) 25 | .andThen(TEXT) 26 | .andThen(PARSE_INT) 27 | ), 28 | 29 | /** 30 | * Locate the integer value representing displayed month on a calendar 31 | */ 32 | DISPLAYED_MONTH( 33 | ORDINAL.compose(TO_MONTH) 34 | .compose(TEXT) 35 | .compose(Locators.element(UI_DATEPICKER_MONTH)) 36 | .compose(Locators.element(UI_DATEPICKER_DIV)) 37 | 38 | ); 39 | 40 | private final Locator locator; 41 | 42 | CalendarIntegerLocator(Locator locator) { 43 | this.locator = locator; 44 | } 45 | 46 | @Override 47 | public Integer locate(Page page) { 48 | return locator.locate(page); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/datepicker/locators/JQueryDayPicker.java: -------------------------------------------------------------------------------- 1 | package com.jquery.datepicker.locators; 2 | 3 | 4 | import com.algocrafts.conditions.Equals; 5 | import com.algocrafts.conditions.PagePredicates; 6 | import com.algocrafts.converters.FirstMatch; 7 | import com.algocrafts.datepicker.DayPicker; 8 | import com.algocrafts.locators.Locators; 9 | import com.algocrafts.pages.Page; 10 | 11 | import static com.algocrafts.converters.ElementFunctions.CLICK; 12 | import static com.algocrafts.converters.GetText.TEXT; 13 | import static com.algocrafts.converters.OptionalGetter.GET; 14 | import static com.algocrafts.locators.Locators.element; 15 | import static com.algocrafts.locators.Locators.elements; 16 | import static com.algocrafts.selectors.ClassName.UI_DATEPICKER_CALENDAR; 17 | import static com.algocrafts.selectors.Id.UI_DATEPICKER_DIV; 18 | import static com.algocrafts.selectors.TagName.TD; 19 | 20 | public class JQueryDayPicker implements DayPicker { 21 | 22 | private Page browser; 23 | private PagePredicates jqueryCalendarNotDisplayed; 24 | 25 | public JQueryDayPicker(Page browser, PagePredicates jqueryCalendarNotDisplayed) { 26 | this.browser = browser; 27 | this.jqueryCalendarNotDisplayed = jqueryCalendarNotDisplayed; 28 | } 29 | 30 | public void pick(int day) { 31 | Locators.element(UI_DATEPICKER_DIV) 32 | .andThen(element(UI_DATEPICKER_CALENDAR)) 33 | .andThen(elements(TD)) 34 | .andThen(new FirstMatch<>(TEXT.and(new Equals(day)))) 35 | .andThen(GET) 36 | .andThen(CLICK).locate(browser); 37 | browser.until(jqueryCalendarNotDisplayed); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/menu/MenuGroupLocator.java: -------------------------------------------------------------------------------- 1 | package com.jquery.menu; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | 7 | import static org.openqa.selenium.By.linkText; 8 | 9 | public class MenuGroupLocator implements Locator { 10 | 11 | private final String menuGroup; 12 | 13 | public MenuGroupLocator(String menuGroup) { 14 | this.menuGroup = menuGroup; 15 | } 16 | 17 | public Element locate(Page page) { 18 | return page.untilFound(() -> linkText(menuGroup)); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "[" + menuGroup + "]"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/jquery/menu/MouseOverMenuLocator.java: -------------------------------------------------------------------------------- 1 | package com.jquery.menu; 2 | 3 | 4 | import com.algocrafts.conditions.Equals; 5 | import com.algocrafts.converters.FirstMatch; 6 | import com.algocrafts.locators.ElementLocator; 7 | import com.algocrafts.pages.Page; 8 | import com.algocrafts.selectors.ClassName; 9 | import com.algocrafts.selenium.Element; 10 | import com.algocrafts.selenium.Locator; 11 | 12 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 13 | import static com.algocrafts.conditions.ElementPredicates.NOT_NULL; 14 | import static com.algocrafts.converters.GetText.TEXT; 15 | import static com.algocrafts.converters.OptionalGetter.GET; 16 | import static com.algocrafts.locators.Locators.elements; 17 | import static com.algocrafts.selectors.Id.GLOBAL_NAV; 18 | import static com.algocrafts.selectors.TagName.LI; 19 | import static com.algocrafts.selectors.TagName.UL; 20 | import static org.openqa.selenium.By.linkText; 21 | 22 | public class MouseOverMenuLocator implements Locator { 23 | 24 | private final String menuGroup; 25 | private final String menuText; 26 | 27 | public MouseOverMenuLocator(String menuGroup, String menuText) { 28 | this.menuGroup = menuGroup; 29 | this.menuText = menuText; 30 | } 31 | 32 | public Element locate(Page page) { 33 | return new ElementLocator(GLOBAL_NAV) 34 | .andThen(new ElementLocator<>(ClassName.L_TINYNAL1)) 35 | .andThen(elements(LI)) 36 | .andThen(new FirstMatch<>(NOT_NULL.and(DISPLAYED).and(TEXT.and(new Equals(menuGroup))))) 37 | .andThen(GET) 38 | .andThen(page.mouseOver()) 39 | .andThen(new ElementLocator<>(UL)) 40 | .andThen(new ElementLocator<>(() -> linkText(menuText))) 41 | .locate(page); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "[" + menuGroup + "->" + menuText + "]"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/orgsync/MenuGroupLocator.java: -------------------------------------------------------------------------------- 1 | package com.orgsync; 2 | 3 | import com.algocrafts.locators.ElementLocator; 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selenium.Element; 6 | import com.algocrafts.selenium.Locator; 7 | 8 | import static com.algocrafts.selectors.Id.MAIN_NAV; 9 | import static org.openqa.selenium.By.linkText; 10 | 11 | public class MenuGroupLocator implements Locator { 12 | 13 | private final String headText; 14 | 15 | public MenuGroupLocator(String menuGroup) { 16 | this.headText = menuGroup; 17 | } 18 | 19 | public Element locate(Page page) { 20 | return new ElementLocator(MAIN_NAV) 21 | .andThen(new ElementLocator<>(() -> linkText(headText))).locate(page); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "[" + headText + "]"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/orgsync/MouseOverLocator.java: -------------------------------------------------------------------------------- 1 | package com.orgsync; 2 | 3 | 4 | import com.algocrafts.conditions.Equals; 5 | import com.algocrafts.converters.FirstMatch; 6 | import com.algocrafts.locators.ElementLocator; 7 | import com.algocrafts.pages.Page; 8 | import com.algocrafts.selenium.Element; 9 | import com.algocrafts.selenium.Locator; 10 | import org.openqa.selenium.By; 11 | 12 | import java.util.function.Supplier; 13 | 14 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 15 | import static com.algocrafts.conditions.ElementPredicates.NOT_NULL; 16 | import static com.algocrafts.converters.GetText.TEXT; 17 | import static com.algocrafts.converters.OptionalGetter.GET; 18 | import static com.algocrafts.locators.Locators.elements; 19 | import static com.algocrafts.selectors.ClassName.SF_JS_ENABLED; 20 | import static com.algocrafts.selectors.Id.MAIN_NAV; 21 | import static com.algocrafts.selectors.TagName.LI; 22 | import static com.algocrafts.selectors.TagName.UL; 23 | import static org.openqa.selenium.By.linkText; 24 | 25 | public class MouseOverLocator implements Locator { 26 | 27 | private final String menuGroup; 28 | private final String menuItem; 29 | 30 | public MouseOverLocator(String menuGroup, String menuItem) { 31 | this.menuGroup = menuGroup; 32 | this.menuItem = menuItem; 33 | } 34 | 35 | public Element locate(Page page) { 36 | return new ElementLocator(MAIN_NAV) 37 | .andThen(new ElementLocator<>(SF_JS_ENABLED)) 38 | .andThen(elements(LI)) 39 | .andThen(new FirstMatch<>(NOT_NULL.and(DISPLAYED).and(TEXT.and(new Equals(menuGroup))))) 40 | .andThen(GET) 41 | .andThen(page.mouseOver()) 42 | .andThen(new ElementLocator<>(UL)) 43 | .andThen(new ElementLocator<>((Supplier) () -> linkText(menuItem))) 44 | .locate(page); 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "[" + menuGroup + "->" + menuItem + "]"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/orgsync/OrgSyncHomePage.java: -------------------------------------------------------------------------------- 1 | package com.orgsync; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selenium.Browser; 6 | import com.algocrafts.selenium.Clickable; 7 | import com.algocrafts.selenium.Locator; 8 | import org.openqa.selenium.WebDriver; 9 | 10 | import java.util.stream.Stream; 11 | 12 | public class OrgSyncHomePage extends Page { 13 | 14 | private final Locator> allMenuLocator; 15 | 16 | public OrgSyncHomePage(Browser browser, 17 | Clickable url, 18 | Locator> allMenuLocator) { 19 | super(browser, url); 20 | this.allMenuLocator = allMenuLocator; 21 | } 22 | 23 | public Stream getAllMenu() { 24 | return allMenuLocator.locate(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/ticketfly/TicketflyEventPage.java: -------------------------------------------------------------------------------- 1 | package com.ticketfly; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | 6 | public class TicketflyEventPage extends Page { 7 | 8 | public TicketflyEventPage(Page page) { 9 | super(page); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/ticketfly/TicketflyPage.java: -------------------------------------------------------------------------------- 1 | package com.ticketfly; 2 | 3 | 4 | import com.algocrafts.clickables.Url; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.pages.Page; 7 | import com.algocrafts.selectors.LinkText; 8 | import com.algocrafts.selenium.Browser; 9 | 10 | import static com.algocrafts.converters.GetText.TEXT; 11 | import static com.algocrafts.locators.Locators.element; 12 | import static com.algocrafts.selectors.ClassName.TOOLS_LOCATION; 13 | import static com.algocrafts.selectors.LinkText.CHANGE_LOCATION; 14 | import static com.algocrafts.selectors.LinkText.DISCOVER_MORE_EVENT; 15 | import static com.algocrafts.selectors.TagName.A; 16 | import static com.algocrafts.selectors.TagName.STRONG; 17 | import static java.util.stream.Stream.of; 18 | 19 | public class TicketflyPage extends Page { 20 | 21 | public TicketflyPage(Browser browser) { 22 | super(browser, new Url<>(browser, "http://www.ticketfly.com")); 23 | } 24 | 25 | public void changeLocation(LinkText first, LinkText second) { 26 | of(CHANGE_LOCATION, first, second).forEach(linkText -> link(linkText).click()); 27 | } 28 | 29 | public void discoverMoreEvent() { 30 | link(DISCOVER_MORE_EVENT).click(); 31 | } 32 | 33 | public String currentLocation() { 34 | return Locators.element(TOOLS_LOCATION) 35 | .andThen(element(A)) 36 | .andThen(element(STRONG)) 37 | .andThen(TEXT) 38 | .locate(this); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/main/resources/bookstore/beans/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/main/resources/bookstore/beans/pages.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/bookstore/beans/properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | classpath:bookstore/properties/page.properties 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/bookstore/properties/page.properties: -------------------------------------------------------------------------------- 1 | entry.url=https://www.manning.com/ 2 | quit.browser=true 3 | take.screenshot=false 4 | browser=CHROME 5 | jbehave.session.timeout=600 6 | jquery.url=http://jqueryui.com/datepicker/ 7 | -------------------------------------------------------------------------------- /src/main/resources/context/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/context/properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | classpath:properties/page.properties 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/html/radio.html: -------------------------------------------------------------------------------- 1 |
6 |
11 |
16 |
21 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Set root logger level to DEBUG and its only appender to A1. 2 | log4j.rootLogger=WARN, A1 3 | 4 | # A1 is set to be a ConsoleAppender. 5 | log4j.appender.A1=org.apache.log4j.ConsoleAppender 6 | 7 | # A1 uses PatternLayout. 8 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout 9 | log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | target/logs/test.log 5 | 6 | 7 | %date %level [%thread] %logger{10} [%file:%line] %msg%n 8 | 9 | 10 | 11 | 12 | 14 | 15 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/resources/properties/page.properties: -------------------------------------------------------------------------------- 1 | entry.url=http://www.orgsync.com/ 2 | quit.browser=true 3 | browser=CHROME 4 | take.screenshot=false 5 | jbehave.session.timeout=600 6 | jquery.url=http://jqueryui.com/datepicker/ 7 | daugherty.url=http://www.daugherty.com/ 8 | entry.url.jquery=https://jquery.org/ 9 | 10 | google.com=https://www.google.com/ 11 | upload.url=http://localhost:63342/seleniumcapsules/html/upload.html 12 | upload.file=src/test/resources/upload/Test.log 13 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/GoogleAutoCompleteTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts; 2 | 3 | import com.algocrafts.locators.Locators; 4 | import com.algocrafts.pages.Page; 5 | import com.google.GooglePage; 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Ignore; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | import static com.algocrafts.locators.Locators.elements; 16 | import static com.algocrafts.selectors.Name.Q; 17 | import static com.algocrafts.selectors.TagName.DIV; 18 | import static com.algocrafts.selectors.Xpath.GOOGLE_AUTOCOMPLETE; 19 | import static org.openqa.selenium.By.id; 20 | 21 | @Ignore 22 | @RunWith(SpringJUnit4ClassRunner.class) 23 | @ContextConfiguration(locations = {"classpath:context/context.xml"}) 24 | public class GoogleAutoCompleteTest { 25 | 26 | @Autowired 27 | GooglePage googlePage; 28 | 29 | @Before 30 | public void setup() { 31 | googlePage.open(); 32 | } 33 | 34 | 35 | /** 36 | * This is a clean test using page framework. it has the same function as the test above. :) 37 | */ 38 | @Test 39 | public void autoCompleteUsingSeleniumCapsules() { 40 | googlePage.autocomplete(Q, "ticketfly", elements(GOOGLE_AUTOCOMPLETE)); 41 | } 42 | 43 | @Ignore 44 | @Test 45 | public void autoCompleteUsingLocator() { 46 | googlePage.autocomplete(Q, "ticketfly", Locators.element(() -> id("sbse0")).andThen(elements(DIV))); 47 | } 48 | 49 | /** 50 | * This is a cleaner test using page framework. it has the same function as the test above. :) 51 | */ 52 | @Test 53 | public void autoCompleteUsingSeleniumCapsules1() { 54 | googlePage.autocomplete("ticketfly"); 55 | } 56 | 57 | @After 58 | public void close() { 59 | googlePage.close(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/OrgSyncHomePageTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts; 2 | 3 | 4 | import com.orgsync.OrgSyncHomePage; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Ignore; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.slf4j.Logger; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | import static org.slf4j.LoggerFactory.getLogger; 16 | 17 | @Ignore 18 | @RunWith(SpringJUnit4ClassRunner.class) 19 | @ContextConfiguration(locations = {"classpath:context/context.xml"}) 20 | public class OrgSyncHomePageTest { 21 | 22 | private static final Logger logger = getLogger(OrgSyncHomePageTest.class); 23 | 24 | @Autowired 25 | private OrgSyncHomePage homePage; 26 | 27 | 28 | @Before 29 | public void setup() { 30 | homePage.open(); 31 | } 32 | 33 | @Test 34 | public void start() { 35 | homePage.getAllMenu().forEach(menu -> { 36 | try { 37 | logger.info("clicking " + menu); 38 | menu.click(); 39 | String title = homePage.getTitle(); 40 | logger.info("clicking " + menu + " and title is \"" + title + "\""); 41 | } catch (Exception e) { 42 | logger.info("Error clicking " + menu, e); 43 | } 44 | }); 45 | } 46 | 47 | @After 48 | public void close() { 49 | homePage.close(); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/SpringUploadTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts; 2 | 3 | 4 | import com.algocrafts.clickables.Url; 5 | import com.algocrafts.pages.Page; 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Ignore; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | import java.io.File; 16 | 17 | import static com.algocrafts.selectors.CssSelector.SUBMIT; 18 | import static com.algocrafts.selectors.Name.FILE; 19 | 20 | @Ignore 21 | @RunWith(SpringJUnit4ClassRunner.class) 22 | @ContextConfiguration(locations = {"classpath:context/context.xml"}) 23 | public class SpringUploadTest { 24 | 25 | @Autowired 26 | private Url uploadUrl; 27 | 28 | @Autowired 29 | private File uploadFile; 30 | 31 | private Page uploadPage; 32 | 33 | @Before 34 | public void openPage() { 35 | uploadPage = new Page(uploadUrl.load()); 36 | } 37 | 38 | @Test 39 | public void fileUpload() { 40 | uploadPage.upload(FILE, SUBMIT, uploadFile); 41 | uploadPage.accept(); 42 | //TODO to add assertion. 43 | } 44 | 45 | @After 46 | public void closeBrowser() { 47 | uploadPage.close(); 48 | } 49 | } 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/TableTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts; 2 | 3 | 4 | import com.algocrafts.browsers.Browsers; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.pages.Page; 7 | import com.algocrafts.pages.Person; 8 | import com.algocrafts.selectors.Xpath; 9 | import com.algocrafts.selenium.Element; 10 | import com.algocrafts.selenium.Locator; 11 | import com.algocrafts.table.Table; 12 | import com.algocrafts.table.TableContents; 13 | import com.google.common.collect.Sets; 14 | import org.junit.Assert; 15 | import org.junit.Ignore; 16 | import org.junit.Test; 17 | 18 | import java.util.Iterator; 19 | import java.util.stream.Stream; 20 | 21 | import static com.algocrafts.converters.GetText.TEXT; 22 | import static com.algocrafts.converters.StringToInt.PARSE_INT; 23 | import static com.algocrafts.locators.Locators.element; 24 | import static com.algocrafts.selectors.TagName.TABLE; 25 | import static com.google.common.collect.Sets.newHashSet; 26 | 27 | @Ignore 28 | public class TableTest { 29 | 30 | private TableContents expected = new TableContents<>( 31 | newHashSet("Number", "First Name", "Last Name", "Points"), 32 | Sets.newHashSet( 33 | new Person(4, "Jill", "Smith", 50) 34 | , new Person(3, "Adam", "Johnson", 67) 35 | , new Person(2, "John", "Doe", 80) 36 | , new Person(1, "Eve", "Jackson", 94) 37 | ) 38 | ); 39 | 40 | @Test 41 | public void testReadFromTable() { 42 | 43 | Browsers browser = Browsers.FIREFOX; 44 | browser.get("http://www.w3schools.com/html/html_tables.asp"); 45 | Page page = new Page(browser); 46 | Locator locator = 47 | Locators.element(Xpath.TABLE_CONTAINER) 48 | .andThen(element(TABLE)); 49 | Locator, Person> mapper = (stream) -> { 50 | Iterator iterator = stream.map(TEXT).iterator(); 51 | return new Person(PARSE_INT.locate(iterator.next()), 52 | iterator.next(), 53 | iterator.next(), 54 | PARSE_INT.locate(iterator.next())); 55 | }; 56 | Table table = new Table<>(page, locator, mapper); 57 | 58 | assertTrue(expected, expected.equals(table.getContents())); 59 | browser.close(); 60 | } 61 | 62 | private void assertTrue(Object diff, boolean pass) { 63 | if (!pass) { 64 | Assert.assertTrue(diff.toString(), pass); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/UploadTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts; 2 | 3 | 4 | import com.algocrafts.pages.Page; 5 | import com.algocrafts.selenium.Browser; 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Ignore; 9 | import org.junit.Test; 10 | 11 | import java.io.File; 12 | 13 | import static com.algocrafts.browsers.Browsers.CHROME; 14 | import static com.algocrafts.selectors.CssSelector.SUBMIT; 15 | import static com.algocrafts.selectors.Name.FILE; 16 | 17 | @Ignore 18 | public class UploadTest { 19 | 20 | private Browser browser = CHROME; 21 | private Page page; 22 | 23 | @Before 24 | public void loadPage() { 25 | browser.get("http://localhost:63342/seleniumcapsules/html/upload.html"); 26 | page = new Page(browser); 27 | } 28 | 29 | @Test 30 | public void fileUpload() { 31 | page.upload(FILE, SUBMIT, new File("src/test/resources/upload/Test.log")); 32 | page.accept(); 33 | //TODO to add assertion. 34 | } 35 | 36 | @After 37 | public void closeBrowser() { 38 | browser.quit(); 39 | } 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter1/BrowserTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter1; 2 | 3 | 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | import org.openqa.selenium.firefox.FirefoxDriver; 11 | import org.openqa.selenium.safari.SafariDriver; 12 | 13 | @Ignore 14 | public class BrowserTest { 15 | 16 | @Test 17 | public void openEmptyFirefox() { 18 | new FirefoxDriver(); 19 | } 20 | 21 | @Test 22 | public void findHowItWorksLinkUsingLinkText() { 23 | WebDriver driver = new ChromeDriver(); 24 | driver.get("http://ticketfly.com/careers"); 25 | WebElement element = driver.findElement(By.linkText("How It Works")); 26 | System.out.println("element=" + element); 27 | System.out.println("element.getTagName()=" + element.getTagName()); 28 | System.out.println("element.getText()=" + element.getText()); 29 | } 30 | 31 | @Test 32 | public void findHowItWorksLinkUsingPartialLinkText() { 33 | WebDriver driver = new SafariDriver(); 34 | driver.get("http://ticketfly.com/careers"); 35 | WebElement element = driver.findElement(By.linkText("How It Works")); 36 | System.out.println("element=" + element); 37 | System.out.println("element.getTagName()=" + element.getTagName()); 38 | System.out.println("element.getText()=" + element.getText()); 39 | } 40 | 41 | @Test 42 | public void findHowItWorksLinkUsingPartialLinkText1() { 43 | WebDriver driver = new FirefoxDriver(); 44 | driver.get("http://ticketfly.com/careers"); 45 | WebElement element = driver.findElement(By.linkText("How It Works")); 46 | System.out.println("element=" + element); 47 | System.out.println("element.getTagName()=" + element.getTagName()); 48 | System.out.println("element.getText()=" + element.getText()); 49 | } 50 | 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter1/LinkClickingTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter1; 2 | 3 | 4 | import com.algocrafts.selectors.LinkText; 5 | import com.algocrafts.selenium.Browser; 6 | import org.junit.Ignore; 7 | import org.junit.Test; 8 | import org.openqa.selenium.By; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | 11 | import static com.algocrafts.browsers.Browsers.CHROME; 12 | 13 | @Ignore 14 | public class LinkClickingTest { 15 | 16 | @Test 17 | public void openChromeAndClickJavaLink() { 18 | ChromeDriver chromeDriver = new ChromeDriver(); 19 | chromeDriver.get("http://manning.com"); 20 | chromeDriver.findElement(By.linkText("Java")).click(); 21 | } 22 | 23 | @Test 24 | public void openChromeAndClickJavaLinkUsingSeleniumCapsules() { 25 | Browser browser = CHROME; 26 | browser.get("http://manning.com"); 27 | browser.link(LinkText.JAVA).click(); 28 | } 29 | 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter13/JQueryDatePickerMultipleBrowserTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter13; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | import com.jquery.datepicker.JQueryDatePickerPage; 5 | import org.apache.commons.lang.time.StopWatch; 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Ignore; 9 | import org.junit.Test; 10 | 11 | import static com.algocrafts.browsers.Browsers.*; 12 | import static java.time.Month.APRIL; 13 | import static java.util.EnumSet.of; 14 | import static org.junit.Assert.assertEquals; 15 | 16 | @Ignore 17 | public class JQueryDatePickerMultipleBrowserTest { 18 | 19 | private StopWatch stopWatch = new StopWatch(); 20 | 21 | @Before 22 | public void startStopWatch() { 23 | stopWatch.start(); 24 | } 25 | 26 | @After 27 | public void print() { 28 | System.out.println("Taken " + stopWatch); 29 | } 30 | 31 | @Test 32 | public void testDifferentBrowsers() { 33 | for (Browser browser : of(CHROME, FIREFOX, SAFARI)) { 34 | JQueryDatePickerPage jQueryDatePickerPage = new JQueryDatePickerPage(browser); 35 | jQueryDatePickerPage.open(); 36 | jQueryDatePickerPage.pick(APRIL, 1, 2012); 37 | assertEquals("04/01/2012", jQueryDatePickerPage.getDate()); 38 | browser.quit(); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter13/JQueryDatePickerTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter13; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.algocrafts.selenium.Browser; 5 | import com.jquery.datepicker.JQueryDatePickerPage; 6 | import org.apache.commons.lang.time.StopWatch; 7 | import org.junit.After; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | import static com.algocrafts.browsers.Browsers.*; 12 | import static java.time.Month.APRIL; 13 | import static java.util.EnumSet.of; 14 | import static org.junit.Assert.assertEquals; 15 | 16 | public class JQueryDatePickerTest { 17 | 18 | private StopWatch stopWatch = new StopWatch(); 19 | 20 | @Before 21 | public void startStopWatch() { 22 | stopWatch.start(); 23 | } 24 | 25 | @After 26 | public void print() { 27 | System.out.println("Taken " + stopWatch); 28 | } 29 | 30 | private JQueryDatePickerPage jQueryDatePickerPage 31 | = new JQueryDatePickerPage(Browsers.CHROME); 32 | 33 | @Before 34 | public void setup() { 35 | jQueryDatePickerPage.open(); 36 | } 37 | 38 | @Test 39 | public void pickADate() { 40 | jQueryDatePickerPage.pick(APRIL, 1, 2012); 41 | assertEquals("04/01/2012", jQueryDatePickerPage.getDate()); 42 | } 43 | 44 | @After 45 | public void close() { 46 | jQueryDatePickerPage.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter13/MuchBetterJQueryDatepicker.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter13; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | 8 | import java.time.Month; 9 | import java.util.Date; 10 | import java.util.List; 11 | 12 | 13 | public class MuchBetterJQueryDatepicker { 14 | 15 | private WebDriver frame; 16 | private WebDriver driver; 17 | 18 | 19 | public String pickDate(Date date) { 20 | 21 | driver = new ChromeDriver(); 22 | driver.get("http://jqueryui.com/datepicker"); 23 | 24 | show(); 25 | pickYear(date.getYear() + 1900); 26 | pickMonth(date.getMonth()); 27 | pickDay(date.getDay() + 1); 28 | 29 | return frame.findElement(By.id("datepicker")).getAttribute("value"); 30 | } 31 | 32 | private void show() { 33 | frame = driver.switchTo().frame(0); 34 | WebElement element = frame.findElement(By.id("datepicker")); 35 | element.click(); 36 | } 37 | 38 | private void pickYear(int year) { 39 | if (displayedYear() < year) { 40 | while (displayedYear() != year) { 41 | nextMonth(); 42 | } 43 | } else if (displayedYear() > year) { 44 | while (displayedYear() != year) { 45 | previousMonth(); 46 | } 47 | } 48 | } 49 | 50 | private void pickMonth(int month) { 51 | if (displayedMonth() < month) { 52 | while (displayedMonth() != month) { 53 | nextMonth(); 54 | } 55 | } else if (displayedMonth() > month) { 56 | while (displayedMonth() != month) { 57 | previousMonth(); 58 | } 59 | } 60 | } 61 | 62 | private void pickDay(int day) { 63 | List tds = calendar().findElements(By.tagName("td")); 64 | for (WebElement td : tds) { 65 | if (td.getText().equals(String.valueOf(day))) { 66 | td.click(); 67 | } 68 | } 69 | } 70 | 71 | private void previousMonth() { 72 | calendar().findElement(By.className("ui-datepicker-prev")).click(); 73 | } 74 | 75 | private void nextMonth() { 76 | calendar().findElement(By.className("ui-datepicker-next")).click(); 77 | } 78 | 79 | private WebElement calendar() { 80 | return frame.findElement(By.id("ui-datepicker-div")); 81 | } 82 | 83 | private int displayedYear() { 84 | return Integer.parseInt(calendar().findElement(By.className("ui-datepicker-year")).getText()); 85 | } 86 | 87 | 88 | private int displayedMonth() { 89 | return Month.valueOf(calendar().findElement(By.className("ui-datepicker-month")).getText().toUpperCase()).ordinal(); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter13/NaiveJQueryDatepickerTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter13; 2 | 3 | import org.apache.commons.lang.time.StopWatch; 4 | import org.junit.After; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.text.ParseException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Date; 11 | 12 | import static org.junit.Assert.assertEquals; 13 | 14 | 15 | public class NaiveJQueryDatepickerTest { 16 | 17 | private StopWatch stopWatch = new StopWatch(); 18 | @Before 19 | public void startStopWatch() { 20 | stopWatch.start(); 21 | } 22 | 23 | @After 24 | public void print() { 25 | System.out.println("Taken " + stopWatch); 26 | } 27 | 28 | private Date date; 29 | 30 | @Before 31 | public void date() throws ParseException { 32 | date = new SimpleDateFormat("MM/dd/yyyy").parse("04/01/2012"); 33 | } 34 | 35 | @Test 36 | public void pickDateUsingNaivaDatepicker() { 37 | assertEquals("04/01/2012", new NaiveDatepicker().pickDate(date)); 38 | } 39 | 40 | @Test 41 | public void pickDateUsingBetterJQueryDatepicker() { 42 | assertEquals("04/01/2012", new BetterJQueryDatepicker().pickDate(date)); 43 | } 44 | 45 | @Test 46 | public void pickDateUsingMuchBetterJQueryDatepicker() { 47 | assertEquals("04/01/2012", new MuchBetterJQueryDatepicker().pickDate(date)); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/AlertTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.*; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | 8 | import java.io.File; 9 | 10 | @Ignore 11 | public class AlertTest { 12 | 13 | @Test 14 | public void dismiss() { 15 | File file = new File("src/test/resources/html/confirm.html"); 16 | WebDriver driver = new ChromeDriver(); 17 | driver.get("file://" + file.getAbsolutePath()); 18 | driver.findElement(By.id("button2")).click(); 19 | 20 | Alert alert = driver.switchTo().alert(); 21 | alert.dismiss(); 22 | } 23 | 24 | @Test 25 | public void accept() { 26 | File file = new File("src/test/resources/html/alert.html"); 27 | WebDriver driver = new ChromeDriver(); 28 | driver.get("file://" + file.getAbsolutePath()); 29 | driver.findElement(By.id("button1")).click(); 30 | 31 | Alert alert = driver.switchTo().alert(); 32 | alert.accept(); 33 | } 34 | 35 | @Test 36 | public void accept2() { 37 | File file = new File("src/test/resources/html/confirm.html"); 38 | WebDriver driver = new ChromeDriver(); 39 | driver.get("file://" + file.getAbsolutePath()); 40 | driver.findElement(By.id("button2")).click(); 41 | 42 | Alert alert = driver.switchTo().alert(); 43 | alert.accept(); 44 | } 45 | 46 | @Test 47 | public void getText() { 48 | File file = new File("src/test/resources/html/confirm.html"); 49 | WebDriver driver = new ChromeDriver(); 50 | driver.get("file://" + file.getAbsolutePath()); 51 | driver.findElement(By.id("button2")).click(); 52 | 53 | Alert alert = driver.switchTo().alert(); 54 | System.out.println(alert.getText()); 55 | } 56 | 57 | @Test 58 | public void sendKeys() { 59 | File file = new File("src/test/resources/html/prompt.html"); 60 | WebDriver driver = new ChromeDriver(); 61 | driver.get("file://" + file.getAbsolutePath()); 62 | driver.findElement(By.id("button2")).click(); 63 | 64 | Alert alert = driver.switchTo().alert(); 65 | alert.sendKeys("35"); 66 | alert.accept(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/ConfirmTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | 4 | import com.algocrafts.selenium.Browser; 5 | import org.junit.Ignore; 6 | import org.junit.Test; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | 10 | import static com.algocrafts.browsers.Browsers.CHROME; 11 | import static com.algocrafts.selectors.CssSelector.NEED_CONIRM; 12 | import static org.openqa.selenium.By.cssSelector; 13 | 14 | @Ignore 15 | public class ConfirmTest { 16 | 17 | @Test 18 | public void clickConfirmUsingSelenium() { 19 | WebDriver driver = new ChromeDriver(); 20 | driver.get("http://localhost:63342/seleniumcapsules/html/upload.html"); 21 | driver.findElement(cssSelector("input[value='Need Confirm']")).click(); 22 | driver.switchTo().alert().accept(); 23 | } 24 | 25 | @Test 26 | public void clickConfirm() { 27 | Browser browser = CHROME; 28 | browser.get("http://localhost:63342/seleniumcapsules/html/upload.html"); 29 | browser.button(NEED_CONIRM).click(); 30 | browser.accept(); 31 | } 32 | 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/CookieTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.Cookie; 6 | import org.openqa.selenium.Dimension; 7 | import org.openqa.selenium.Point; 8 | import org.openqa.selenium.WebDriver; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | 11 | import java.util.Set; 12 | 13 | import static org.openqa.selenium.WebDriver.Options; 14 | import static org.openqa.selenium.WebDriver.Window; 15 | 16 | @Ignore 17 | public class CookieTest { 18 | 19 | @Test 20 | public void cookies() { 21 | WebDriver driver = new ChromeDriver(); 22 | driver.get("http://ticketfly.com"); 23 | 24 | Options manage = driver.manage(); 25 | manage.getCookies().stream().forEach(System.out::println); 26 | manage.deleteAllCookies(); 27 | System.out.println("After manage.deleteAllCookies();"); 28 | manage.getCookies().stream().forEach(System.out::println); 29 | System.out.println("After adding two cookies"); 30 | 31 | manage.addCookie(new Cookie("Test", "just for test")); 32 | manage.addCookie(new Cookie("Test2", "just for test too")); 33 | manage.getCookies().stream().forEach(System.out::println); 34 | 35 | Cookie test = manage.getCookieNamed("Test"); 36 | System.out.println("Test Cookie is:" + test); 37 | manage.deleteCookie(test); 38 | 39 | manage.deleteCookieNamed("Test2"); 40 | System.out.println("After deleting two cookies"); 41 | manage.getCookies().stream().forEach(System.out::println); 42 | System.out.println("Done"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/ImeHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.firefox.FirefoxDriver; 8 | import org.openqa.selenium.logging.LogEntries; 9 | import org.openqa.selenium.logging.LogEntry; 10 | import org.openqa.selenium.logging.Logs; 11 | import org.openqa.selenium.safari.SafariDriver; 12 | 13 | import java.util.List; 14 | import java.util.Set; 15 | import java.util.logging.Level; 16 | 17 | import static org.openqa.selenium.WebDriver.Options; 18 | 19 | /** 20 | * Created by yujunliang on 8/31/14. 21 | */ 22 | @Ignore 23 | public class ImeHandlerTest { 24 | 25 | @Test 26 | public void getAvailableEngines() { 27 | WebDriver driver = new ChromeDriver(); 28 | driver.get("http://ticketfly.com"); 29 | 30 | Options manage = driver.manage(); 31 | WebDriver.ImeHandler ime = manage.ime(); 32 | ime.getAvailableEngines(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/LogsTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.Alert; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | import org.openqa.selenium.logging.LogEntries; 10 | import org.openqa.selenium.logging.LogEntry; 11 | import org.openqa.selenium.logging.Logs; 12 | 13 | import java.io.File; 14 | import java.util.List; 15 | import java.util.Set; 16 | import java.util.logging.Level; 17 | 18 | import static org.openqa.selenium.WebDriver.Options; 19 | 20 | @Ignore 21 | public class LogsTest { 22 | 23 | @Test 24 | public void getAvailableLogTypes() { 25 | WebDriver driver = new ChromeDriver(); 26 | driver.get("http://ticketfly.com"); 27 | 28 | Options manage = driver.manage(); 29 | Logs logs = manage.logs(); 30 | Set availableLogTypes = logs.getAvailableLogTypes(); 31 | System.out.println(availableLogTypes); 32 | availableLogTypes.stream().forEach(logType -> { 33 | System.out.println("logType=" + logType); 34 | LogEntries logEntries = logs.get(logType); 35 | List all = logEntries.getAll(); 36 | all.forEach(entry -> { 37 | System.out.println(entry.getLevel()); 38 | System.out.println(entry.getMessage()); 39 | System.out.println(entry.getTimestamp()); 40 | System.out.println(entry.toMap()); 41 | System.out.println(entry); 42 | }); 43 | 44 | List filter = logEntries.filter(Level.SEVERE); 45 | System.out.println("After filtering"); 46 | filter.forEach(System.out::println); 47 | System.out.println("Done"); 48 | }); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/NavigationTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.Alert; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | 10 | import java.io.File; 11 | import java.net.MalformedURLException; 12 | import java.net.URL; 13 | 14 | import static org.openqa.selenium.WebDriver.Navigation; 15 | 16 | @Ignore 17 | public class NavigationTest { 18 | 19 | @Test 20 | public void navagate() throws InterruptedException, MalformedURLException { 21 | WebDriver driver = new ChromeDriver(); 22 | 23 | driver.get("http://ticketfly.com"); 24 | driver.get("http://jqueryui.com"); 25 | 26 | Navigation navigate = driver.navigate(); 27 | navigate.back(); 28 | System.out.println("navigate.back()=" + driver.getCurrentUrl()); 29 | 30 | navigate.forward(); 31 | System.out.println("navigate.forward()=" + driver.getCurrentUrl()); 32 | 33 | navigate.to("http://ticketfly.com/events"); 34 | System.out.println("navigate.to(\"http://ticketfly.com/events\")=" 35 | + driver.getCurrentUrl()); 36 | 37 | navigate.to(new URL("http://jqueryui.com/datepicker")); 38 | System.out.println("navigate.to(new URL(\"http://jqueryui.com/datepicker\"))=" 39 | + driver.getCurrentUrl()); 40 | 41 | navigate.refresh(); 42 | System.out.println("navigate.refresh()=" 43 | + driver.getCurrentUrl()); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/WindowsTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.openqa.selenium.Dimension; 6 | import org.openqa.selenium.Point; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.chrome.ChromeDriver; 9 | 10 | import static org.openqa.selenium.WebDriver.Options; 11 | import static org.openqa.selenium.WebDriver.Window; 12 | 13 | /** 14 | * Created by yujunliang on 8/31/14. 15 | */ 16 | @Ignore 17 | public class WindowsTest { 18 | 19 | @Test 20 | public void windowsOperations() { 21 | WebDriver driver = new ChromeDriver(); 22 | driver.get("http://ticketfly.com"); 23 | 24 | Options manage = driver.manage(); 25 | Window window = manage.window(); 26 | System.out.println("window.getPosition()=" + window.getPosition()); 27 | System.out.println("window.getSize()=" + window.getSize()); 28 | 29 | window.maximize(); 30 | System.out.println(" window.maximize() - first call"); 31 | System.out.println("window.getPosition()=" + window.getPosition()); 32 | System.out.println("window.getSize()=" + window.getSize()); 33 | 34 | window.maximize(); 35 | System.out.println(" window.maximize() - second call"); 36 | System.out.println("window.getPosition()=" + window.getPosition()); 37 | System.out.println("window.getSize()=" + window.getSize()); 38 | 39 | window.setPosition(new Point(200,400)); 40 | window.setSize(new Dimension(400, 800)); 41 | 42 | System.out.println("after setPosition and setSize"); 43 | System.out.println("window.getPosition()=" + window.getPosition()); 44 | System.out.println("window.getSize()=" + window.getSize()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/BetterWebDriverFactory.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | 4 | import com.algocrafts.browsers.ChromeDriverSupplier; 5 | import com.algocrafts.browsers.FirefoxDriverSupplier; 6 | import com.algocrafts.browsers.HeadlessFirefoxDriverSupplierOnLinux; 7 | import com.algocrafts.browsers.HeadlessFirefoxDriverSupplierOnMacOs; 8 | import com.algocrafts.browsers.InternetExplorerDriverSupplier; 9 | import com.algocrafts.browsers.SafariDriverSupplier; 10 | import com.algocrafts.selenium.CachedWebDriverSupplier; 11 | import org.openqa.selenium.WebDriver; 12 | 13 | import java.util.function.Supplier; 14 | 15 | public enum BetterWebDriverFactory implements Supplier { 16 | 17 | FIREFOX(new FirefoxDriverSupplier()) , 18 | CHROME(new ChromeDriverSupplier()), 19 | HEADLESS_MAC(new HeadlessFirefoxDriverSupplierOnMacOs()), 20 | HEADLESS_LINUX(new HeadlessFirefoxDriverSupplierOnLinux()), 21 | SAFARI(new SafariDriverSupplier()), 22 | INTERNET_EXPLORER(new InternetExplorerDriverSupplier()); 23 | 24 | private BetterWebDriverFactory(CachedWebDriverSupplier driverDecorator) { 25 | this.webDriverSupplier = driverDecorator; 26 | } 27 | 28 | private final CachedWebDriverSupplier webDriverSupplier; 29 | 30 | public WebDriver get() { 31 | return webDriverSupplier.get(); 32 | } 33 | 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/Browser.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import com.algocrafts.selenium.*; 4 | import org.openqa.selenium.*; 5 | import org.openqa.selenium.interactions.HasInputDevices; 6 | 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | public interface Browser extends WebDriver, CachedWebDriverSupplier, SearchScope>, 11 | HasInputDevices, JavascriptExecutor, HasCapabilities { 12 | 13 | CachedWebDriverSupplier getSupplier(); 14 | 15 | @Override 16 | default public T init() { 17 | return getSupplier().init(); 18 | } 19 | 20 | @Deprecated 21 | @Override 22 | default public Element findElement(By by) { 23 | return new ElementFinder(by).locate(get()); 24 | } 25 | 26 | @Deprecated 27 | @Override 28 | default public List findElements(By by) { 29 | return new ElementsFinder(by).locate(get()); 30 | } 31 | 32 | @Override 33 | default public void get(String url) { 34 | get().get(url); 35 | } 36 | 37 | @Override 38 | default public String getCurrentUrl() { 39 | return get().getCurrentUrl(); 40 | } 41 | 42 | @Override 43 | default public String getTitle() { 44 | return get().getTitle(); 45 | } 46 | 47 | @Override 48 | default public String getPageSource() { 49 | return get().getPageSource(); 50 | } 51 | 52 | @Override 53 | default public Set getWindowHandles() { 54 | return get().getWindowHandles(); 55 | } 56 | 57 | @Override 58 | default public String getWindowHandle() { 59 | return get().getWindowHandle(); 60 | } 61 | 62 | @Override 63 | default public TargetLocator switchTo() { 64 | return get().switchTo(); 65 | } 66 | 67 | @Override 68 | default public Navigation navigate() { 69 | return get().navigate(); 70 | } 71 | 72 | @Override 73 | default public Options manage() { 74 | return get().manage(); 75 | } 76 | 77 | @Override 78 | default public void close() { 79 | get().close(); 80 | } 81 | 82 | @Override 83 | default public void quit() { 84 | store.valueOf(this).quit(); 85 | store.remove(this); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/ChromeDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import org.openqa.selenium.chrome.ChromeDriver; 4 | 5 | import java.util.function.Supplier; 6 | 7 | public class ChromeDriverSupplier implements Supplier { 8 | 9 | @Override 10 | public ChromeDriver get() { 11 | return new ChromeDriver(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/FirefoxDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import org.openqa.selenium.firefox.FirefoxBinary; 4 | import org.openqa.selenium.firefox.FirefoxDriver; 5 | import org.openqa.selenium.firefox.FirefoxProfile; 6 | 7 | import java.io.File; 8 | import java.util.function.Supplier; 9 | 10 | public class FirefoxDriverSupplier implements Supplier { 11 | @Override 12 | public FirefoxDriver get() { 13 | String binaryDir = "src/main/resources/Firefox/Contents/MacOS/firefox-bin"; 14 | File firefoxBinary = new File(binaryDir); 15 | FirefoxBinary binary = new FirefoxBinary(firefoxBinary); 16 | String dirName = "src/main/resources/Firefox/Profiles/default"; 17 | File profileDir = new File(dirName); 18 | FirefoxProfile profile = new FirefoxProfile(profileDir); 19 | return new FirefoxDriver(binary, profile); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/FirefoxDriverSupplierOnWindows.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | import com.algocrafts.selenium.CachedWebDriverSupplier; 5 | import org.openqa.selenium.firefox.FirefoxBinary; 6 | import org.openqa.selenium.firefox.FirefoxDriver; 7 | import org.openqa.selenium.firefox.FirefoxProfile; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * This class is not one of the enum constants enum Browsers. It is used to demonstrate how to implement the Browser 13 | * interface thus used as the constructor parameter for AbstractPage. It is declared as a bean in spring context file, 14 | *

15 | * <bean id="firefox" class="com.algocrafts.browsers.FirefoxOnWindows"/> 16 | *

17 | * and it is referenced by ref attribute of the containing bean. 18 | *

19 | * However, the enum browser is referenced by value, 20 | * <constructor-arg value="${browser}"/> 21 | *

22 | * in property file, 23 | * browser=CHROME 24 | *

25 | * The other browsers known to enum don't implement Browser interface, they just implement WebDriverSupplier<T> 26 | */ 27 | public class FirefoxDriverSupplierOnWindows implements Browser, CachedWebDriverSupplier { 28 | 29 | public FirefoxDriver init() { 30 | FirefoxBinary binary = new FirefoxBinary(new File("src/main/resources/Firefox/firefox.exe")); 31 | FirefoxProfile profile = new FirefoxProfile(new File("src/main/resources/Firefox/Profiles/default")); 32 | return new FirefoxDriver(binary, profile); 33 | } 34 | 35 | @Override 36 | public CachedWebDriverSupplier getSupplier() { 37 | return this; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/HeadlessFirefoxDriverSupplierOnLinux.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.firefox.FirefoxBinary; 5 | import org.openqa.selenium.firefox.FirefoxDriver; 6 | import org.openqa.selenium.firefox.FirefoxProfile; 7 | 8 | import java.io.File; 9 | 10 | 11 | public class HeadlessFirefoxDriverSupplierOnLinux implements CachedWebDriverSupplier { 12 | @Override 13 | public FirefoxDriver init() { 14 | FirefoxBinary binary = new FirefoxBinary(new File("/opt/local/lib/firefox-x11/firefox-bin")); 15 | binary.setEnvironmentProperty("DISPLAY", ":88"); 16 | return new FirefoxDriver(binary, new FirefoxProfile()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/HeadlessFirefoxDriverSupplierOnMacOs.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import org.openqa.selenium.firefox.FirefoxBinary; 4 | import org.openqa.selenium.firefox.FirefoxDriver; 5 | import org.openqa.selenium.firefox.FirefoxProfile; 6 | 7 | import java.io.File; 8 | import java.util.function.Supplier; 9 | 10 | 11 | public class HeadlessFirefoxDriverSupplierOnMacOs implements Supplier { 12 | @Override 13 | public FirefoxDriver get() { 14 | FirefoxBinary binary = new FirefoxBinary(new File("/opt/local/lib/firefox-x11/firefox-bin")); 15 | binary.setEnvironmentProperty("DISPLAY", ":88"); 16 | return new FirefoxDriver(binary, new FirefoxProfile()); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/InternetExplorerDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import com.algocrafts.selenium.CachedWebDriverSupplier; 4 | import org.openqa.selenium.ie.InternetExplorerDriver; 5 | 6 | 7 | public class InternetExplorerDriverSupplier implements CachedWebDriverSupplier { 8 | @Override 9 | public InternetExplorerDriver init() { 10 | return new InternetExplorerDriver(); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/NaiveWebDriverFactory.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | 4 | import org.openqa.selenium.WebDriver; 5 | 6 | public class NaiveWebDriverFactory { 7 | 8 | public static WebDriver getInstance(String webDriverType) { 9 | if (webDriverType.equals("firefox")) { 10 | new FirefoxDriverSupplier().get(); 11 | } else if (webDriverType.equals("chrome")) { 12 | new ChromeDriverSupplier().get(); 13 | } else if (webDriverType.equals("safari")) { 14 | new SafariDriverSupplier().get(); 15 | } 16 | throw new UnsupportedOperationException("Unknow browser type"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter2/factory/SafariDriverSupplier.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter2.factory; 2 | 3 | import org.openqa.selenium.safari.SafariDriver; 4 | 5 | import java.util.function.Supplier; 6 | 7 | public class SafariDriverSupplier implements Supplier { 8 | @Override 9 | public SafariDriver get() { 10 | return new SafariDriver(); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/ActionsTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3; 2 | 3 | 4 | import org.junit.Ignore; 5 | import org.junit.Test; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.Keys; 8 | import org.openqa.selenium.WebDriver; 9 | import org.openqa.selenium.WebElement; 10 | import org.openqa.selenium.chrome.ChromeDriver; 11 | import org.openqa.selenium.firefox.FirefoxDriver; 12 | import org.openqa.selenium.interactions.Actions; 13 | 14 | import java.util.concurrent.TimeUnit; 15 | 16 | @Ignore 17 | public class ActionsTest { 18 | 19 | @Test 20 | public void keyDown() { 21 | WebDriver driver = new ChromeDriver(); 22 | driver.get("http://www.ticketfly.com"); 23 | 24 | Actions actions= new Actions(driver); 25 | WebElement element = driver.findElement(By.xpath("//body")); 26 | actions.keyDown(element, Keys.COMMAND).sendKeys(element,"a").perform(); 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/DiscoverMoreEventTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | 6 | import com.ticketfly.TicketflyPage; 7 | import static com.algocrafts.browsers.Browsers.CHROME; 8 | import static com.algocrafts.selectors.Name.FILTER_EVENT; 9 | 10 | @Ignore 11 | public class DiscoverMoreEventTest { 12 | 13 | @Test 14 | public void discoverMoreEvent() { 15 | TicketflyPage page = new TicketflyPage(CHROME); 16 | page.open(); 17 | page.discoverMoreEvent(); 18 | page.setRadioButton(FILTER_EVENT, "Just Announced"); 19 | } 20 | 21 | @Test 22 | public void discoverMoreEventAnonymousClass() { 23 | new TicketflyPage(CHROME) {{ 24 | open(); 25 | discoverMoreEvent(); 26 | setRadioButton(FILTER_EVENT, "Just Announced"); 27 | }}; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/TicketflyPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3; 2 | 3 | import com.algocrafts.selectors.LinkText; 4 | import com.algocrafts.selectors.Xpath; 5 | import com.algocrafts.selenium.Browser; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public class TicketflyPage { 10 | private final Browser browser; 11 | private final String url = "http://www.ticketfly.com"; 12 | 13 | public TicketflyPage(Browser browser) { 14 | this.browser = browser; 15 | } 16 | 17 | public void open() { 18 | browser.get(url); 19 | } 20 | 21 | public void changeLocation(LinkText first, LinkText second) { //<1> 22 | Stream.of(LinkText.CHANGE_LOCATION, first, second).forEach( //<2> 23 | linkText -> browser.untilFound(linkText).click()); 24 | } 25 | 26 | public String currentLocation() { //<3> 27 | return browser.untilFound(Xpath.LOCATION).getText(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/inheritance/BaseTicketflyPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.inheritance; 2 | 3 | import com.algocrafts.selectors.LinkText; 4 | import com.algocrafts.selectors.Xpath; 5 | import com.algocrafts.selenium.Browser; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public class BaseTicketflyPage { 10 | private final Browser browser; 11 | private final String url; 12 | 13 | public BaseTicketflyPage(Browser browser, String url) { 14 | this.browser = browser; 15 | this.url = url; 16 | } 17 | 18 | public void open() { 19 | browser.get(url); 20 | } 21 | 22 | public void changeLocation(LinkText first, LinkText second) { 23 | Stream.of(LinkText.CHANGE_LOCATION, first, second).forEach( 24 | linkText -> browser.untilFound(linkText).click()); 25 | } 26 | 27 | public String currentLocation() { 28 | return browser.untilFound(Xpath.LOCATION).getText(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/inheritance/TicketflyCareerPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.inheritance; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyCareerPage extends BaseTicketflyPage { 6 | 7 | public TicketflyCareerPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/careers"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/inheritance/TicketflyEventPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.inheritance; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyEventPage extends BaseTicketflyPage { 6 | 7 | public TicketflyEventPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/events"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/inheritance/TicketflyHomePage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.inheritance; 2 | 3 | import com.algocrafts.selectors.LinkText; 4 | import com.algocrafts.selectors.Xpath; 5 | import com.algocrafts.selenium.Browser; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public class TicketflyHomePage extends BaseTicketflyPage { 10 | 11 | public TicketflyHomePage(Browser browser) { 12 | super(browser, "http://www.ticketfly.com"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/interfaces/BaseTicketflyPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.interfaces; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Browser; 5 | import com.algocrafts.selenium.Element; 6 | import com.algocrafts.selenium.SearchScope; 7 | import org.openqa.selenium.By; 8 | 9 | public class BaseTicketflyPage implements SearchScope { 10 | private final Browser browser; 11 | private final String url; 12 | 13 | public BaseTicketflyPage(Browser browser, String url) { 14 | this.browser = browser; 15 | this.url = url; 16 | } 17 | 18 | public void open() { 19 | browser.get(url); 20 | } 21 | 22 | @Override 23 | public final void onTimeout() { 24 | browser.save(browser.getTitle()); 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/interfaces/ChangeLocation.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.interfaces; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selectors.LinkText; 5 | import com.algocrafts.selectors.Xpath; 6 | import com.algocrafts.selenium.SearchScope; 7 | 8 | import java.util.stream.Stream; 9 | 10 | public interface ChangeLocation extends SearchScope { 11 | 12 | default void changeLocation(LinkText first, LinkText second) { 13 | Stream.of(LinkText.CHANGE_LOCATION, first, second).forEach( 14 | linkText -> this.untilFound(linkText).click()); 15 | } 16 | 17 | default String currentLocation() { 18 | return this.untilFound(Xpath.LOCATION).getText(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/interfaces/TicketflyCareerPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.interfaces; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyCareerPage extends BaseTicketflyPage { 6 | 7 | public TicketflyCareerPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/careers"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/interfaces/TicketflyEventPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.interfaces; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyEventPage extends BaseTicketflyPage implements ChangeLocation{ 6 | 7 | public TicketflyEventPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/events"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/interfaces/TicketflyHomePage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.interfaces; 2 | 3 | import com.algocrafts.selectors.LinkText; 4 | import com.algocrafts.selectors.Xpath; 5 | import com.algocrafts.selenium.Browser; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public class TicketflyHomePage extends BaseTicketflyPage implements ChangeLocation { 10 | 11 | public TicketflyHomePage(Browser browser) { 12 | super(browser, "http://www.ticketfly.com"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/page/ChangeLocation.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.page; 2 | 3 | import com.algocrafts.selectors.LinkText; 4 | import com.algocrafts.selectors.Xpath; 5 | import com.algocrafts.selenium.SearchScope; 6 | 7 | import java.util.stream.Stream; 8 | 9 | public interface ChangeLocation extends SearchScope { 10 | 11 | default void changeLocation(LinkText first, LinkText second) { 12 | Stream.of(LinkText.CHANGE_LOCATION, first, second).forEach( 13 | linkText -> this.untilFound(linkText).click()); 14 | } 15 | 16 | default String currentLocation() { 17 | return this.untilFound(Xpath.LOCATION).getText(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/page/Page.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.page; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.SearchScope; 6 | import org.openqa.selenium.By; 7 | import org.openqa.selenium.WebElement; 8 | 9 | import java.util.List; 10 | 11 | public class Page implements SearchScope { 12 | 13 | private final Browser browser; 14 | private final String url; 15 | 16 | public Page(Page page, String url) { 17 | this(page.browser, url); 18 | } 19 | 20 | public Page(Browser browser, String url) { 21 | this.browser = browser; 22 | this.url = url; 23 | } 24 | 25 | public final void open() { 26 | browser.get(url); 27 | } 28 | 29 | @Override 30 | public List findElements(By by) { 31 | return browser.findElements(by); 32 | } 33 | 34 | @Override 35 | public final Element findElement(final By by) { 36 | return browser.findElement(by); 37 | } 38 | 39 | @Override 40 | public final void onTimeout() { 41 | browser.save(browser.getTitle()); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/page/TicketflyCareerPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.page; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyCareerPage extends Page { 6 | 7 | public TicketflyCareerPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/careers"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/page/TicketflyEventPage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.page; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyEventPage extends Page implements ChangeLocation { 6 | 7 | public TicketflyEventPage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com/events"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter3/page/TicketflyHomePage.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter3.page; 2 | 3 | import com.algocrafts.selenium.Browser; 4 | 5 | public class TicketflyHomePage extends Page implements ChangeLocation { 6 | 7 | public TicketflyHomePage(Browser browser) { 8 | super(browser, "http://www.ticketfly.com"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter4/ByConstants.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter4; 2 | 3 | 4 | import org.openqa.selenium.By; 5 | 6 | public class ByConstants { 7 | 8 | public static final By QUANTITY = By.name("cartDS.shoppingcart_ROW0_m_orderItemVector_ROW0_m_quantity"); 9 | 10 | public static final By SF_JS_ENABLED = By.className("sf-js-enabled"); 11 | public static final By TOOLS_LOCATION = By.className("tools-location"); 12 | 13 | public static final By UI_DATEPICKER_CALENDAR = By.className("ui-datepicker-calendar"); 14 | public static final By UI_DATEPICKER_NEXT = By.className("ui-datepicker-next"); 15 | public static final By UI_DATEPICKER_PREV = By.className("ui-datepicker-prev"); 16 | public static final By UI_DATEPICKER_MONTH = By.className("ui-datepicker-month"); 17 | public static final By UI_DATEPICKER_YEAR = By.className("ui-datepicker-year"); 18 | public static final By UI_DATEPICKER_HEADER = By.className("ui-datepicker-header"); 19 | public static final By PAGE_TITLE = By.className("page-title"); 20 | public static final By UI_DATEPICKER_CLOSE = By.className("ui-datepicker-close"); 21 | 22 | public static final By UPDATE = By.cssSelector("input[value='Update']"); 23 | public static final By CONTINUE = By.cssSelector("input[value='Continue']"); 24 | public static final By NEED_CONIRM = By.cssSelector("input[value='Need Confirm']"); 25 | public static final By SUBMIT = By.cssSelector("input[type='Submit']"); 26 | 27 | public static final By LOCATION = By.id("location"); 28 | public static final By MAIN = By.id("main"); 29 | public static final By MAIN_NAV = By.id("main-nav"); 30 | public static final By UI_DATEPICKER_DIV = By.id("ui-datepicker-div"); 31 | public static final By CONTENT = By.id("content"); 32 | public static final By EXTJS_DATEPICKER_TRIGGER = By.id("menuitem-1017-textEl"); 33 | public static final By EXTJS_CALENDAR = By.id("datemenu-1014"); 34 | public static final By EXTJS_CALENDAR_MONTH_YEAR = By.id("splitbutton-1020-btnInnerEl"); 35 | public static final By EXTJS_CALENDAR_PREV_MONTH = By.id("datepicker-1015-prevEl"); 36 | public static final By EXTJS_CALENDAR_NEXT_MONTH = By.id("datepicker-1015-nextEl"); 37 | public static final By DATE_PICKER = By.id("datepicker"); 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter4/unused/TypeToLocateAnElement.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter4.unused; 2 | 3 | import com.algocrafts.selenium.Element; 4 | 5 | import java.util.Optional; 6 | 7 | public interface TypeToLocateAnElement { 8 | Optional locate(Element element); 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter5/JQueryHomePageTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter5; 2 | 3 | 4 | import com.jquery.JQueryHomePage; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Ignore; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.slf4j.Logger; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | import static org.slf4j.LoggerFactory.getLogger; 16 | 17 | @Ignore 18 | @RunWith(SpringJUnit4ClassRunner.class) 19 | @ContextConfiguration(locations = {"classpath:context/context.xml"}) 20 | public class JQueryHomePageTest { 21 | 22 | private static final Logger logger = getLogger(JQueryHomePageTest.class); 23 | 24 | @Autowired 25 | private JQueryHomePage jQueryHomePage; 26 | 27 | 28 | @Before 29 | public void setup() { 30 | jQueryHomePage.open(); 31 | } 32 | 33 | @Test 34 | public void start() { 35 | jQueryHomePage.getAllMenu().forEach(menu -> { 36 | try { 37 | logger.info("clicking " + menu); 38 | jQueryHomePage.open(); 39 | menu.click(); 40 | String title = jQueryHomePage.getTitle(); 41 | logger.info("clicking " + menu + " and title is \"" + title + "\""); 42 | } catch (Exception e) { 43 | logger.info("Error clicking " + menu, e); 44 | } 45 | }); 46 | } 47 | 48 | @After 49 | public void close() { 50 | jQueryHomePage.close(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter5/Menu.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter5; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | import org.slf4j.Logger; 7 | 8 | import static org.slf4j.LoggerFactory.getLogger; 9 | 10 | public class Menu { 11 | 12 | private static final Logger log = getLogger(Menu.class); 13 | private final Page page; 14 | private final Locator locator; 15 | 16 | public Menu(Page page, Locator locator) { 17 | this.locator = locator; 18 | this.page = page; 19 | } 20 | 21 | public void click() { 22 | Element menu = locator.locate(page); 23 | log.info("clicking [" + menu + "]"); 24 | menu.click(); 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return locator.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter5/MenuGroupLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter5; 2 | 3 | import com.algocrafts.pages.Page; 4 | import com.algocrafts.selenium.Element; 5 | import com.algocrafts.selenium.Locator; 6 | import org.openqa.selenium.By; 7 | 8 | public class MenuGroupLocator implements Locator { 9 | 10 | private final String menuGroup; 11 | 12 | public MenuGroupLocator(String menuGroup) { 13 | this.menuGroup = menuGroup; 14 | } 15 | 16 | public Element locate(Page page) { 17 | return page.untilFound(() -> By.linkText(menuGroup)); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "[" + menuGroup + "]"; 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter5/MouseOverMenuLocator.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter5; 2 | 3 | import com.algocrafts.conditions.Equals; 4 | import com.algocrafts.converters.FirstMatch; 5 | import com.algocrafts.locators.Locators; 6 | import com.algocrafts.pages.Page; 7 | import com.algocrafts.selectors.ClassName; 8 | import com.algocrafts.selenium.Element; 9 | import com.algocrafts.selenium.Locator; 10 | 11 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 12 | import static com.algocrafts.converters.GetText.TEXT; 13 | import static com.algocrafts.converters.OptionalGetter.GET; 14 | import static com.algocrafts.locators.Locators.element; 15 | import static com.algocrafts.locators.Locators.elements; 16 | import static com.algocrafts.selectors.Id.GLOBAL_NAV; 17 | import static com.algocrafts.selectors.TagName.LI; 18 | import static com.algocrafts.selectors.TagName.UL; 19 | import static org.openqa.selenium.By.linkText; 20 | 21 | public class MouseOverMenuLocator implements Locator { 22 | 23 | private final String menuGroup; 24 | private final String menuText; 25 | 26 | public MouseOverMenuLocator(String menuGroup, String menuText) { 27 | this.menuGroup = menuGroup; 28 | this.menuText = menuText; 29 | } 30 | 31 | public Element locate(Page page) { 32 | return Locators.element(GLOBAL_NAV) 33 | .andThen(element(ClassName.L_TINYNAL1)) 34 | .andThen(elements(LI)) 35 | .andThen(new FirstMatch<>(DISPLAYED 36 | .and(TEXT.and(new Equals(menuGroup))))) 37 | .andThen(GET) 38 | .andThen(page.mouseOver()) 39 | .andThen(element(UL)) 40 | .andThen(element(() -> linkText(menuText))) 41 | .locate(page); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "[" + menuGroup + "->" + menuText + "]"; 47 | } 48 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/chapter5/NaiveJQueryHomePageTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.chapter5; 2 | 3 | 4 | import com.algocrafts.locators.Locators; 5 | import com.algocrafts.selectors.TagName; 6 | import com.algocrafts.selenium.Browser; 7 | import com.algocrafts.selenium.Element; 8 | import org.junit.Ignore; 9 | import org.junit.Test; 10 | import org.openqa.selenium.chrome.ChromeDriver; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Optional; 15 | import java.util.stream.Stream; 16 | 17 | import static com.algocrafts.browsers.Browsers.CHROME; 18 | import static com.algocrafts.conditions.ElementPredicates.DISPLAYED; 19 | import static com.algocrafts.conditions.OptionalPresents.PRESENT; 20 | import static com.algocrafts.selectors.ClassName.L_TINYNAL1; 21 | import static com.algocrafts.selectors.Id.GLOBAL_NAV; 22 | import static com.algocrafts.selectors.TagName.LI; 23 | import static com.algocrafts.selectors.TagName.UL; 24 | import static java.util.stream.Collectors.toList; 25 | 26 | 27 | @Ignore 28 | public class NaiveJQueryHomePageTest { 29 | 30 | @Test 31 | public void mouseOver4() { 32 | Browser browser = CHROME; 33 | browser.get("https://jquery.org"); 34 | List elements = browser.untilFound(GLOBAL_NAV) 35 | .untilFound(L_TINYNAL1) 36 | .findElements(LI) 37 | .filter(DISPLAYED.and(Locators.optionalElement(UL).and(PRESENT.negate()).or( 38 | Locators.optionalElement(LI).and(PRESENT)))).collect(toList()); 39 | List menu = new ArrayList<>(); 40 | elements.forEach(menubarElement -> { 41 | Element link = menubarElement.untilFound(TagName.A); 42 | System.out.println("Menu Bar[" + link.getText() + "]"); 43 | menu.add(link); 44 | browser.mouseOver(menubarElement); 45 | Optional optionalElement = menubarElement.optionalElement(UL); 46 | if (optionalElement.isPresent()) { 47 | Stream meneElements = optionalElement.get() 48 | .findElements(LI) 49 | .map(liElement -> { 50 | Element menuElement = liElement.untilFound(TagName.A); 51 | System.out.println(" |-- Menu[" + menuElement.getText() + "]"); 52 | return menuElement; 53 | }); 54 | menu.addAll(meneElements.collect(toList())); 55 | } 56 | } 57 | ); 58 | 59 | menu.forEach(Element::click); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/converters/ToMonthTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.converters; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.algocrafts.converters.StringToMonth.TO_MONTH; 6 | import static java.time.Month.APRIL; 7 | import static java.time.Month.JANUARY; 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class ToMonthTest { 11 | 12 | @Test 13 | public void test() { 14 | assertEquals(APRIL, TO_MONTH.locate("apr")); 15 | assertEquals(APRIL, TO_MONTH.locate("apr.")); 16 | assertEquals(APRIL, TO_MONTH.locate("Apr.")); 17 | assertEquals(APRIL, TO_MONTH.locate("April")); 18 | assertEquals(JANUARY, TO_MONTH.locate("Jan.")); 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/cucumber/ChangeLocationStep.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.cucumber; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.algocrafts.selectors.LinkText; 5 | import com.ticketfly.TicketflyPage; 6 | import cucumber.api.java.en.Given; 7 | import cucumber.api.java.en.Then; 8 | import cucumber.api.java.en.When; 9 | 10 | 11 | import static org.junit.Assert.assertEquals; 12 | 13 | public class ChangeLocationStep { 14 | 15 | TicketflyPage page; 16 | 17 | @Given("^I am on TicketFly home page using (.+)$") 18 | public void given(String browser) { 19 | page = new TicketflyPage(Browsers.valueOf(browser)); 20 | page.open(); 21 | } 22 | 23 | @When("^I change the location to (.+) then (.+)$") 24 | public void changeLocation(String country, String region) { 25 | page.changeLocation(LinkText.resolve(country), LinkText.resolve(region)); 26 | } 27 | 28 | @Then("^the default location is (.+)$") 29 | public void verifyLocation(String location) { 30 | assertEquals(location, page.currentLocation()); 31 | page.close(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/cucumber/RunCucumberTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.cucumber; 2 | 3 | import cucumber.api.CucumberOptions; 4 | import cucumber.api.junit.Cucumber; 5 | import org.junit.Ignore; 6 | import org.junit.runner.RunWith; 7 | 8 | @Ignore 9 | @RunWith(Cucumber.class) 10 | @CucumberOptions(plugin = {"pretty", "html:target/cucumber", "json:target/cucumber.json"}) 11 | public class RunCucumberTest { 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/cucumber/SelectCalendarStep.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.cucumber; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.jquery.datepicker.JQueryDatePickerPage; 5 | import cucumber.api.java8.En; 6 | 7 | import static com.algocrafts.converters.StringToMonth.TO_MONTH; 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class SelectCalendarStep implements En { 11 | 12 | JQueryDatePickerPage page; 13 | 14 | public SelectCalendarStep() { 15 | Given("^I am on jQuery Calendar page using (.+)$", (String browser) -> { 16 | System.out.println("Running...."); 17 | Browsers browser1 = Browsers.valueOf(browser); 18 | page = new JQueryDatePickerPage(browser1); 19 | page.open(); 20 | }); 21 | 22 | When("^I pick (.+), (\\d+), (\\d+) from a datepicker$", (String month, Integer day, Integer year) -> { 23 | page.pick(TO_MONTH.locate(month), day, year); 24 | }); 25 | 26 | Then("^datepicker result is (.+)$", (String date) -> { 27 | assertEquals(date, page.getDate()); 28 | }); 29 | 30 | And("^I close browser$", () -> { 31 | page.quit(); 32 | }); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/jbehave/ChangeLocationStep.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.jbehave; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.algocrafts.selectors.LinkText; 5 | import com.ticketfly.TicketflyPage; 6 | import org.jbehave.core.annotations.Given; 7 | import org.jbehave.core.annotations.Then; 8 | import org.jbehave.core.annotations.When; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class ChangeLocationStep { 13 | 14 | TicketflyPage page; 15 | 16 | @Given("I am on TicketFly home page using $browser") 17 | public void given(String browser) { 18 | page = new TicketflyPage(Browsers.valueOf(browser)); 19 | page.open(); 20 | } 21 | 22 | @When("I change the location to $county then $region") 23 | public void changeLocation(String country, String region) { 24 | page.changeLocation(LinkText.valueOf(country), LinkText.valueOf(region)); 25 | } 26 | 27 | @Then("the default location is $location") 28 | public void verifyLocation(String location) { 29 | assertEquals(location, page.currentLocation()); 30 | page.close(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/jbehave/SelectCalendarStep.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.jbehave; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.algocrafts.selenium.Browser; 5 | import com.jquery.datepicker.JQueryDatePickerPage; 6 | import org.jbehave.core.annotations.Given; 7 | import org.jbehave.core.annotations.Then; 8 | import org.jbehave.core.annotations.When; 9 | 10 | import static com.algocrafts.converters.StringToMonth.TO_MONTH; 11 | import static org.junit.Assert.assertEquals; 12 | 13 | public class SelectCalendarStep { 14 | 15 | JQueryDatePickerPage page; 16 | 17 | @Given("I am on jQuery Calendar page using ") 18 | public void given(String browser) { 19 | Browser browser1 = Browsers.valueOf(browser); 20 | page = new JQueryDatePickerPage(browser1); 21 | page.open(); 22 | } 23 | 24 | @When("I pick , , from a datepicker") 25 | public void pick(String month, int day, int year) { 26 | page.pick(TO_MONTH.locate(month), day, year); 27 | } 28 | 29 | @Then("datepicker result is ") 30 | public void verify(String date) { 31 | assertEquals(date, page.getDate()); 32 | } 33 | 34 | @Then("I close browser") 35 | public void close() { 36 | page.quit(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/pages/BrowsersTest.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.pages; 2 | 3 | import com.algocrafts.browsers.Browsers; 4 | import com.algocrafts.selenium.Browser; 5 | import org.junit.Test; 6 | 7 | public class BrowsersTest { 8 | 9 | @Test 10 | public void testGetSupplier() throws Exception { 11 | Browser firefox = Browsers.FIREFOX; 12 | firefox = Browsers.CHROME; 13 | firefox = Browsers.HEADLESS_LINUX; 14 | firefox = Browsers.SAFARI; 15 | firefox = Browsers.HEADLESS_MAC; 16 | firefox = Browsers.INTERNET_EXPLORER; 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/java/com/algocrafts/pages/Person.java: -------------------------------------------------------------------------------- 1 | package com.algocrafts.pages; 2 | 3 | import static org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals; 4 | import static org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode; 5 | 6 | public class Person { 7 | private int number; 8 | private final String firstName; 9 | private final String lastName; 10 | private final int points; 11 | 12 | public Person(int number, String firstName, String lastName, int points) { 13 | this.number = number; 14 | this.firstName = firstName; 15 | this.lastName = lastName; 16 | this.points = points; 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | return "new Person(\"" + number + 22 | "\",\"" + firstName + "\",\"" + 23 | lastName + "\"," + points + ")\n"; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object other) { 28 | return reflectionEquals(this, other); 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | return reflectionHashCode(this); 34 | } 35 | } -------------------------------------------------------------------------------- /src/test/java/daugherty/HomePageTest.java: -------------------------------------------------------------------------------- 1 | package daugherty; 2 | 3 | 4 | import com.daugherty.DaughertyHomePage; 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Ignore; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.slf4j.Logger; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | import static org.slf4j.LoggerFactory.getLogger; 16 | 17 | @Ignore 18 | @RunWith(SpringJUnit4ClassRunner.class) 19 | @ContextConfiguration(locations = {"/context/context.xml"}) 20 | public class HomePageTest { 21 | 22 | private static final Logger logger = getLogger(HomePageTest.class); 23 | 24 | @Autowired 25 | private DaughertyHomePage daughertyHomePage; 26 | 27 | @Before 28 | public void setup() { 29 | daughertyHomePage.open(); 30 | } 31 | 32 | @Test 33 | public void start() { 34 | daughertyHomePage.getAllMenu().forEach(menu -> { 35 | try { 36 | menu.click(); 37 | String title = daughertyHomePage.getTitle(); 38 | logger.info("clicking " + menu + " and title is \"" + title + "\""); 39 | } catch (Exception e) { 40 | logger.info("Error clicking " + menu, e); 41 | } 42 | }); 43 | } 44 | 45 | @After 46 | public void close() { 47 | daughertyHomePage.close(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/com/algocrafts/cucumber/change_location.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | As an event goer 3 | I want to change the default location to my location 4 | So that I can easily find out the local events 5 | 6 | Scenario: Goto home page and change the location to desired location 7 | Given I am on TicketFly home page using CHROME 8 | When I change the location to CANADA then All Canada 9 | Then the default location is Canada 10 | 11 | Given I am on TicketFly home page using FIREFOX 12 | When I change the location to CANADA then All Canada 13 | Then the default location is Canada 14 | 15 | Given I am on TicketFly home page using SAFARI 16 | When I change the location to CANADA then All Canada 17 | Then the default location is Canada 18 | 19 | Given I am on TicketFly home page using HEADLESS_MAC 20 | When I change the location to CANADA then All Canada 21 | Then the default location is Canada -------------------------------------------------------------------------------- /src/test/resources/com/algocrafts/cucumber/change_location_tabular.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | As an event goer 3 | I want to change the default location to my location 4 | So that I can easily find out the local events 5 | 6 | Scenario Outline: Goto home page and change the location to desired location 7 | Given I am on TicketFly home page using 8 | When I change the location to then 9 | Then the default location is 10 | 11 | Examples: 12 | | browser | country | location | result | 13 | | CHROME | CANADA | All Canada | Canada | 14 | | SAFARI | CANADA | All Canada | Canada | 15 | | HEADLESS_MAC | CANADA | All Canada | Canada | 16 | | FIREFOX | CANADA | All Canada | Canada | 17 | -------------------------------------------------------------------------------- /src/test/resources/com/algocrafts/cucumber/select_calendar.feature: -------------------------------------------------------------------------------- 1 | Feature: 2 | As a user 3 | I want to select a specific date from datepicker 4 | So that I can populate the date filed on the form 5 | 6 | Scenario Outline: Select a date using datepicker on jQuery datepicker demo page 7 | Given I am on jQuery Calendar page using 8 | When I pick , , from a datepicker 9 | Then datepicker result is 10 | And I close browser 11 | 12 | Examples: browsers 13 | |browser |month |day|year|date | 14 | |CHROME |September|19 |2014|09/19/2014 | 15 | |FIREFOX |Aug |5 |2010|08/05/2010 | 16 | |SAFARI |July |4 |2014|07/04/2014 | 17 | |HEADLESS_MAC|Sep |12 |2014|09/12/2014 | 18 | -------------------------------------------------------------------------------- /src/test/resources/com/algocrafts/jbehave/change_location.story: -------------------------------------------------------------------------------- 1 | Narrative: 2 | As an event goer 3 | I want to change the default location to my location 4 | So that I can easily find out the local events 5 | 6 | Scenario: Goto home page and change the location to desired location 7 | Given I am on TicketFly home page using CHROME 8 | When I change the location to CANADA then ALL_CANADA 9 | Then the default location is Canada 10 | 11 | Given I am on TicketFly home page using FIREFOX 12 | When I change the location to CANADA then ALL_CANADA 13 | Then the default location is Canada 14 | 15 | Given I am on TicketFly home page using SAFARI 16 | When I change the location to CANADA then ALL_CANADA 17 | Then the default location is Canada 18 | 19 | Given I am on TicketFly home page using HEADLESS_MAC 20 | When I change the location to CANADA then ALL_CANADA 21 | Then the default location is Canada -------------------------------------------------------------------------------- /src/test/resources/com/algocrafts/jbehave/select_calendar.story: -------------------------------------------------------------------------------- 1 | Narrative: 2 | As a user 3 | I want to select a specific date from datepicker 4 | So that I can populate the date filed on the form 5 | 6 | Scenario: Select a date using datepicker on jQuery datepicker demo page 7 | Given I am on jQuery Calendar page using 8 | When I pick , , from a datepicker 9 | Then datepicker result is 10 | And I close browser 11 | 12 | Examples: 13 | 14 | |browser |month |day|year|date 15 | |CHROME |September|19 |2014|09/19/2014 16 | |FIREFOX |Aug |5 |2010|08/05/2010 17 | |HEADLESS_MAC|Sep |12 |2014|09/12/2014 18 | -------------------------------------------------------------------------------- /src/test/resources/configuration-namespace.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | target/classes 10 | TXT 11 | HTML 12 | CONSOLE 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | target/classes 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | CONSOLE 42 | TXT 43 | HTML 44 | XML 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/test/resources/html/alert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/test/resources/html/confirm.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/html/date.html: -------------------------------------------------------------------------------- 1 | 2 | Please enter date in format MM/dd/YYYY -------------------------------------------------------------------------------- /src/test/resources/html/iframeDemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/test/resources/html/openWindow.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/resources/html/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "glossary": { 3 | "title": "example glossary", 4 | "GlossDiv": { 5 | "title": "S", 6 | "GlossList": { 7 | "GlossEntry": { 8 | "ID": "SGML", 9 | "SortAs": "SGML", 10 | "GlossTerm": "Standard Generalized Markup Language", 11 | "Acronym": "SGML", 12 | "Abbrev": "ISO 8879:1986", 13 | "GlossDef": { 14 | "para": "A meta-markup language, used to create markup languages such as DocBook.", 15 | "GlossSeeAlso": ["GML", "XML"] 16 | }, 17 | "GlossSee": "markup" 18 | } 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/html/prompt.html: -------------------------------------------------------------------------------- 1 | 7 | Your age is unkonwn. 8 | -------------------------------------------------------------------------------- /src/test/resources/html/upload.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 |
5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | target/logs/test.log 5 | 6 | 7 | %date %level [%thread] %logger{10} [%file:%line] %msg%n 8 | 9 | 10 | 11 | 12 | 14 | 15 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/resources/upload/Test.log: -------------------------------------------------------------------------------- 1 | This file is for upload purpose. -------------------------------------------------------------------------------- /start-headless.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | xvfb :88 -screen 0 1024x768x8 & 3 | export DISPLAY=:88 4 | --------------------------------------------------------------------------------