package com.tyndalehouse.step.test; import com.saucelabs.common.SauceOnDemandAuthentication; import com.saucelabs.common.SauceOnDemandSessionIdProvider; import com.saucelabs.junit.ConcurrentParameterized; import com.saucelabs.junit.SauceOnDemandTestWatcher; import org.junit.*; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.service.DriverService; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.LinkedList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; /** * Demonstrates how to write a JUnit test that runs tests against Sauce Labs using multiple browsers in parallel. * <p/> * The test also includes the {@link SauceOnDemandTestWatcher} which will invoke the Sauce REST API to mark * the test as passed or failed. * * @author Ross Rowe */ @RunWith(ConcurrentParameterized.class) public abstract class AbstractSTEPTest implements SauceOnDemandSessionIdProvider { /** * Constructs a {@link SauceOnDemandAuthentication} instance using the supplied user name/access key. To use the authentication * supplied by environment variables or from an external file, use the no-arg {@link SauceOnDemandAuthentication} constructor. */ public SauceOnDemandAuthentication authentication; /** * JUnit Rule which will mark the Sauce Job as passed/failed when the test succeeds or fails. */ @Rule public SauceOnDemandTestWatcher resultReportingTestWatcher; /** * Represents the browser to be used as part of the test run. */ private String browser; /** * Represents the operating system to be used as part of the test run. */ private String os; /** * Represents the version of the browser to be used as part of the test run. */ private String version; /** * Instance variable which contains the Sauce Job Id. */ private String sessionId; /** * The {@link WebDriver} instance which is used to perform browser interactions with. */ private WebDriver driver; /** * Chrome driver (or equivalent) */ private static DriverService service = null; /** * Constructs a new instance of the test. The constructor requires three string parameters, which represent the operating * system, version and browser to be used when launching a Sauce VM. The order of the parameters should be the same * as that of the elements within the {@link #browsersStrings()} method. * * @param os * @param version * @param browser */ public AbstractSTEPTest(String os, String version, String browser) { super(); this.os = os; this.version = version; this.browser = browser; if (System.getProperty("local") == null) { this.authentication = new SauceOnDemandAuthentication(System.getProperty("sauceUsername"), System.getProperty("saucePassword")); this.resultReportingTestWatcher = new SauceOnDemandTestWatcher(this, authentication); } } /** * @return a LinkedList containing String arrays representing the browser combinations the test should be run against. The values * in the String array are used as part of the invocation of the test constructor */ @ConcurrentParameterized.Parameters public static LinkedList browsersStrings() { LinkedList browsers = new LinkedList(); browsers.add(new String[]{"Windows 8.1", null, "chrome"}); if(System.getProperty("local") == null) { //internet explorer on all windows versions browsers.add(new String[]{"Windows 8.1", "11", "internet explorer"}); browsers.add(new String[]{"Windows 8", "10", "internet explorer"}); browsers.add(new String[]{"Windows 7", "9", "internet explorer"}); //chrome & opera browsers.add(new String[]{"Linux", null, "opera"}); //firefox browsers.add(new String[]{"Windows 8.1", null, "firefox"}); //mac osx browsers.add(new String[]{"OSX 10.8", null, "safari"}); browsers.add(new String[]{"OSX 10.9", null, "safari"}); browsers.add(new String[]{"OSX 10.10", null, "safari"}); } return browsers; } @BeforeClass public static void start() throws IOException { if (System.getProperty("local") != null) { service = new ChromeDriverService.Builder() .usingDriverExecutable(new File("c:\\dev\\tools\\chromedriver.exe")) .usingAnyFreePort() .build(); service.start(); } } /** * Constructs a new {@link RemoteWebDriver} instance which is configured to use the capabilities defined by the {@link #browser}, * {@link #version} and {@link #os} instance variables, and which is configured to run against ondemand.saucelabs.com, using * the username and access key populated by the {@link #authentication} instance. * * @throws Exception if an error occurs during the creation of the {@link RemoteWebDriver} instance. */ @Before public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(CapabilityType.BROWSER_NAME, browser); if (version != null) { capabilities.setCapability(CapabilityType.VERSION, version); } capabilities.setCapability(CapabilityType.PLATFORM, os); capabilities.setCapability("name", "STEP Integration tests"); if (System.getProperty("local") != null) { this.driver = new RemoteWebDriver(service.getUrl(), DesiredCapabilities.chrome()); } else { if(authentication.getUsername() == null || authentication.getAccessKey() == null) { fail("No login credentials for sauce. Maybe use -Dlocal to execute locally"); } this.driver = new RemoteWebDriver( new URL("http://" + authentication.getUsername() + ":" + authentication.getAccessKey() + "@ondemand.saucelabs.com:80/wd/hub"), capabilities); } this.sessionId = (((RemoteWebDriver) driver).getSessionId()).toString(); } /** * Closes the {@link WebDriver} session. * * @throws Exception */ @After public void tearDown() throws Exception { driver.quit(); } @AfterClass public static void finish() { if (service != null) { service.stop(); } } /** * @return the value of the Sauce Job id. */ @Override public String getSessionId() { return sessionId; } public WebDriver getDriver() { return driver; } public String getDefaultURL() { return System.getProperty("url") == null ? "http://dev.stepbible.org" : System.getProperty("url"); } public void openHomePage() { getDriver().get(getDefaultURL()); } public void openHomePage(String language) { openHomePage(); getDriver().findElement(By.linkText("Language")).click(); getDriver().findElement(By.xpath(String.format("//a[@lang='%s']", language))).click(); } }