├── .sauce.yml
├── .gitignore
├── Jenkinsfile
├── src
└── test
│ └── java
│ └── com
│ └── yourcompany
│ ├── Tests
│ ├── FollowLinkTest.java
│ ├── TextInputTest.java
│ └── TestBase.java
│ └── Pages
│ └── GuineaPigPage.java
├── .travis.yml
├── pom.xml
└── README.md
/.sauce.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: "java"
3 | maven-version: "3.3"
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | target
3 | .idea
4 | *.iml
5 | .DS_Store
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | node {
2 | def mvnHome = tool 'Maven'
3 |
4 | // Mark the code checkout 'stage'....
5 | stage 'Checkout'
6 | // Get some code from a GitHub repository
7 | git url: 'https://github.com/saucelabs-sample-test-frameworks/Java-Junit-Selenium.git'
8 | stage 'Compile'
9 | sh "${mvnHome}/bin/mvn compile"
10 | stage 'Test'
11 | sauce('saucelabs') {
12 | sauceconnect(useGeneratedTunnelIdentifier: true, verboseLogging: true) {
13 | sh "${mvnHome}/bin/mvn test"
14 | }
15 | }
16 | stage 'Collect Results'
17 | step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
18 | step([$class: 'SauceOnDemandTestPublisher'])
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/java/com/yourcompany/Tests/FollowLinkTest.java:
--------------------------------------------------------------------------------
1 | package com.yourcompany.Tests;
2 |
3 | import com.yourcompany.Pages.*;
4 | import org.junit.Test;
5 | import org.openqa.selenium.InvalidElementStateException;
6 |
7 | import static org.junit.Assert.*;
8 |
9 | public class FollowLinkTest extends TestBase {
10 |
11 | public FollowLinkTest(String os,
12 | String version, String browser, String deviceName, String deviceOrientation) {
13 | super(os, version, browser, deviceName, deviceOrientation);
14 | }
15 |
16 | /**
17 | * Runs a simple test verifying link can be followed.
18 | * @throws InvalidElementStateException
19 | */
20 | @Test
21 | public void verifyLinkTest() throws InvalidElementStateException {
22 | GuineaPigPage page = GuineaPigPage.visitPage(driver);
23 |
24 | page.followLink();
25 |
26 | assertFalse(page.isOnPage());
27 | }
28 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | before_install:
5 | - export | grep SAUCE_
6 | script: mvn clean test
7 | env:
8 | global:
9 | - BUILD_TAG=$TRAVIS_REPO_SLUG+$TRAVIS_BUILD_NUMBER
10 | - SAUCE_USERNAME=sauce_examples
11 | addons:
12 | jwt:
13 | secure: i6R/B/3F45mhSfu0/7iFmcWYHv97lp+mR35qqmXJ0SstIcmgtAKxSrxh9nTzi+Cy8arX1MRwGYrSTFZh9wGGREkJ52hfzZe3VFWDbqdmX/oPxI5xU/50kYKyMl0D5L3dKerhvkBvUVEY+AC6vSkurQ46bfzF0i//hW4ymhUElUnvc72Kj85SKMIu+sWitDVu4LZPkdDiPSq7ExnPMg2mwfSALLR2BwoAwZ8IYff0r30RsJQqhRzrkoBoX4WU2PTHnZbUlYE1yXiAPmsWrASEB+GsqpKgscPpi1jZYdjYNDedOpTv/pDCfLuyGk48v2MqJHEUc77ASLh9H9HBt9a+lwGanwdnxVE6ywsr+pbb1bKG5PmC4RcskZfpvxa6Saosj/+LdPHXcujjaKJhiHOG0C/x6FdqYeYdzjBXiy0WbY2d4Ht6IGOZoE5gU7AMUt8hQq3ygaqJ8Y8c2C7n00BQ2NbrBxrDsJs4soi6oFSrSkGqz9viLg3y8GHvmrGTKuXjoSiaD48Vidr+KHaL5mlHPVbvQEY4OT0YB79O1scZ53pNLH8vKGPoYOepDIZBnv4UBK2BmGdxfPEcLbSnK5uh6SG6qZN3qQzETL/jPGAzIqVn0zcfjWdgwrNrZgGuZhUpcQbhJPoG+g8F6+KHJL/UQf+bqnTEIh1fPjCklcZ/+KQ=
14 |
--------------------------------------------------------------------------------
/src/test/java/com/yourcompany/Tests/TextInputTest.java:
--------------------------------------------------------------------------------
1 | package com.yourcompany.Tests;
2 |
3 | import com.yourcompany.Pages.*;
4 | import org.junit.Test;
5 | import org.openqa.selenium.InvalidElementStateException;
6 | import static org.hamcrest.CoreMatchers.containsString;
7 |
8 | import java.util.UUID;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | public class TextInputTest extends TestBase {
13 |
14 | public TextInputTest(String os,
15 | String version, String browser, String deviceName, String deviceOrientation) {
16 | super(os, version, browser, deviceName, deviceOrientation);
17 | }
18 |
19 | /**
20 | * Runs a simple test verifying if the comment input is functional.
21 | * @throws InvalidElementStateException
22 | */
23 | @Test
24 | public void verifyCommentInputTest() throws InvalidElementStateException {
25 | String commentInputText = UUID.randomUUID().toString();
26 |
27 | GuineaPigPage page = GuineaPigPage.visitPage(driver);
28 | page.visitPage();
29 | page.submitComment(commentInputText);
30 |
31 | assertThat(page.getSubmittedCommentText(), containsString(commentInputText));
32 | }
33 | }
--------------------------------------------------------------------------------
/src/test/java/com/yourcompany/Pages/GuineaPigPage.java:
--------------------------------------------------------------------------------
1 | package com.yourcompany.Pages;
2 |
3 | import org.openqa.selenium.WebDriver;
4 | import org.openqa.selenium.WebElement;
5 | import org.openqa.selenium.support.FindBy;
6 | import org.openqa.selenium.support.PageFactory;
7 | import org.openqa.selenium.support.ui.WebDriverWait;
8 | import org.openqa.selenium.support.ui.ExpectedConditions;
9 |
10 | public class GuineaPigPage {
11 |
12 | @FindBy(linkText = "i am a link")
13 | private WebElement theActiveLink;
14 |
15 | @FindBy(id = "your_comments")
16 | private WebElement yourCommentsSpan;
17 |
18 | @FindBy(id = "comments")
19 | private WebElement commentsTextAreaInput;
20 |
21 | @FindBy(id = "submit")
22 | private WebElement submitButton;
23 |
24 | public WebDriver driver;
25 | public static String url = "https://saucelabs-sample-test-frameworks.github.io/training-test-page";
26 |
27 | public static GuineaPigPage visitPage(WebDriver driver) {
28 | GuineaPigPage page = new GuineaPigPage(driver);
29 | page.visitPage();
30 | return page;
31 | }
32 |
33 | public GuineaPigPage(WebDriver driver) {
34 | this.driver = driver;
35 | PageFactory.initElements(driver, this);
36 | }
37 |
38 | public void visitPage() {
39 | this.driver.get(url);
40 | }
41 |
42 | public void followLink() {
43 | this.theActiveLink.click();
44 | }
45 |
46 | public void submitComment(String text) {
47 | this.commentsTextAreaInput.sendKeys(text);
48 | this.submitButton.click();
49 |
50 | // Race condition for time to populate yourCommentsSpan
51 | WebDriverWait wait = new WebDriverWait(this.driver, 15);
52 | wait.until(ExpectedConditions.textToBePresentInElement(yourCommentsSpan, text));
53 | }
54 |
55 | public String getSubmittedCommentText() {
56 | return this.yourCommentsSpan.getText();
57 | }
58 |
59 | public boolean isOnPage() {
60 | String title = "I am a page title - Sauce Labs";
61 | return this.driver.getTitle() == title;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | java-junit-selenium
6 | com.saucelabs
7 | 1.0-SNAPSHOT
8 | jar
9 | java-junit-selenium
10 | A sample Maven project that demonstrates how to integrate Sauce OnDemand with WebDriver tests
11 | that run using JUnit
12 |
13 |
14 |
15 |
16 | junit
17 | junit
18 | 4.12
19 | test
20 |
21 |
22 | org.seleniumhq.selenium
23 | selenium-java
24 | 2.53.1
25 | test
26 |
27 |
28 | com.saucelabs
29 | sauce_junit
30 | 2.1.20
31 | test
32 |
33 |
34 |
35 |
36 |
37 | maven-compiler-plugin
38 | 3.0
39 |
40 | 1.7
41 | 1.7
42 |
43 |
44 |
45 | org.apache.maven.plugins
46 | maven-surefire-plugin
47 |
48 | classes
49 | 40
50 |
51 | false
52 |
53 | 2.12.4
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Java-Junit-Selenium
2 | [](https://travis-ci.org/saucelabs-sample-test-frameworks/Java-Junit-Selenium)
3 |
4 | This code is provided on an "AS-IS” basis without warranty of any kind, either express or implied, including without limitation any implied warranties of condition, uninterrupted use, merchantability, fitness for a particular purpose, or non-infringement. Your tests and testing environments may require you to modify this framework. Issues regarding this framework should be submitted through GitHub. For questions regarding Sauce Labs integration, please see the Sauce Labs documentation at https://wiki.saucelabs.com/. This framework is not maintained by Sauce Labs Support.
5 |
6 | ### Environment Setup
7 |
8 | 1. Global Dependencies
9 | * Install [Maven](https://maven.apache.org/install.html)
10 | * Or Install Maven with [Homebrew](http://brew.sh/) (Easier)
11 | ```
12 | $ brew install maven
13 | ```
14 | 2. Sauce Labs Credentials
15 | * In the terminal, export your Sauce Labs credentials as environmental variables:
16 | ```
17 | $ export SAUCE_USERNAME=
18 | $ export SAUCE_ACCESS_KEY=
19 | ```
20 | 3. Project Dependencies
21 | * Check that packages are available
22 | ```
23 | $ cd Java-Junit-Selenium
24 | $ mvn test-compile
25 | ```
26 | * You may also want to run the command below to check for outdated dependencies. Please be sure to verify and review updates before editing your pom.xml file as they may not be compatible with your code.
27 | ```
28 | $ mvn versions:display-dependency-updates
29 | ```
30 |
31 | ### Running Tests
32 |
33 | #####Testing in Parallel:
34 | ```
35 | $ mvn test
36 | ```
37 | [Sauce Labs Dashboard](https://saucelabs.com/beta/dashboard/)
38 |
39 | ### Advice/Troubleshooting
40 | 1. It may be useful to use a Java IDE such as IntelliJ or Eclipse to help troubleshoot potential issues.
41 | 2. There may be additional latency when using a remote webdriver to run tests on Sauce Labs. Timeouts and/or waits may need to be increased.
42 | * [Selenium tips regarding explicit waits](https://wiki.saucelabs.com/display/DOCS/Best+Practice%3A+Use+Explicit+Waits)
43 |
44 | ### Resources
45 | ##### [Sauce Labs Documentation](https://wiki.saucelabs.com/)
46 |
47 | ##### [SeleniumHQ Documentation](http://www.seleniumhq.org/docs/)
48 |
49 | ##### [Junit Documentation](http://junit.org/javadoc/latest/index.html)
50 |
51 | ##### [Java Documentation](https://docs.oracle.com/javase/7/docs/api/)
52 |
53 | ##### [Stack Overflow](http://stackoverflow.com/)
54 | * A great resource to search for issues not explicitly covered by documentation.
55 |
56 |
--------------------------------------------------------------------------------
/src/test/java/com/yourcompany/Tests/TestBase.java:
--------------------------------------------------------------------------------
1 | package com.yourcompany.Tests;
2 |
3 | import com.saucelabs.common.SauceOnDemandAuthentication;
4 |
5 | import org.junit.*;
6 | import org.junit.rules.TestName;
7 | import org.junit.runner.RunWith;
8 | import org.openqa.selenium.WebDriver;
9 | import org.openqa.selenium.remote.CapabilityType;
10 | import org.openqa.selenium.remote.DesiredCapabilities;
11 | import org.openqa.selenium.remote.RemoteWebDriver;
12 |
13 | import com.saucelabs.junit.ConcurrentParameterized;
14 | import com.saucelabs.junit.SauceOnDemandTestWatcher;
15 |
16 | import java.net.URL;
17 | import java.util.LinkedList;
18 |
19 | import com.saucelabs.common.SauceOnDemandSessionIdProvider;
20 |
21 |
22 |
23 | /**
24 | * Demonstrates how to write a JUnit test that runs tests against Sauce Labs using multiple browsers in parallel.
25 | *
26 | * The test also includes the {@link SauceOnDemandTestWatcher} which will invoke the Sauce REST API to mark
27 | * the test as passed or failed.
28 | *
29 | * @author Neil Manvar
30 | */
31 | @Ignore
32 | @RunWith(ConcurrentParameterized.class)
33 | public class TestBase implements SauceOnDemandSessionIdProvider {
34 |
35 | public static String username = System.getenv("SAUCE_USERNAME");
36 | public static String accesskey = System.getenv("SAUCE_ACCESS_KEY");
37 | public static String seleniumURI;
38 | public static String buildTag;
39 | /**
40 | * Constructs a {@link SauceOnDemandAuthentication} instance using the supplied user name/access key. To use the authentication
41 | * supplied by environment variables or from an external file, use the no-arg {@link SauceOnDemandAuthentication} constructor.
42 | */
43 | public SauceOnDemandAuthentication authentication = new SauceOnDemandAuthentication(username, accesskey);
44 |
45 | /**
46 | * JUnit Rule which will mark the Sauce Job as passed/failed when the test succeeds or fails.
47 | */
48 | @Rule
49 | public SauceOnDemandTestWatcher resultReportingTestWatcher = new SauceOnDemandTestWatcher(this, authentication);
50 |
51 | @Rule
52 | public TestName name = new TestName() {
53 | public String getMethodName() {
54 | return String.format("%s", super.getMethodName());
55 | }
56 | };
57 |
58 | protected String browser;
59 | protected String os;
60 | protected String version;
61 | protected String deviceName;
62 | protected String deviceOrientation;
63 | protected String sessionId;
64 | protected WebDriver driver;
65 |
66 | /**
67 | * Constructs a new instance of the test. The constructor requires three string parameters, which represent the operating
68 | * system, version and browser to be used when launching a Sauce VM. The order of the parameters should be the same
69 | * as that of the elements within the {@link #browsersStrings()} method.
70 | * @param os
71 | * @param version
72 | * @param browser
73 | * @param deviceName
74 | * @param deviceOrientation
75 | */
76 |
77 | public TestBase(String os, String version, String browser, String deviceName, String deviceOrientation) {
78 | super();
79 | this.os = os;
80 | this.version = version;
81 | this.browser = browser;
82 | this.deviceName = deviceName;
83 | this.deviceOrientation = deviceOrientation;
84 | }
85 |
86 | /**
87 | * @return a LinkedList containing String arrays representing the browser combinations the test should be run against. The values
88 | * in the String array are used as part of the invocation of the test constructor
89 | */
90 | @ConcurrentParameterized.Parameters
91 | public static LinkedList browsersStrings() {
92 | LinkedList browsers = new LinkedList();
93 |
94 | browsers.add(new String[]{"Windows 10", "14.14393", "MicrosoftEdge", null, null});
95 | browsers.add(new String[]{"Windows 10", "49.0", "firefox", null, null});
96 | browsers.add(new String[]{"Windows 7", "11.0", "internet explorer", null, null});
97 | browsers.add(new String[]{"OS X 10.11", "10.0", "safari", null, null});
98 | browsers.add(new String[]{"OS X 10.10", "54.0", "chrome", null, null});
99 | return browsers;
100 | }
101 |
102 | /**
103 | * Constructs a new {@link RemoteWebDriver} instance which is configured to use the capabilities defined by the {@link #browser},
104 | * {@link #version} and {@link #os} instance variables, and which is configured to run against ondemand.saucelabs.com, using
105 | * the username and access key populated by the {@link #authentication} instance.
106 | *
107 | * @throws Exception if an error occurs during the creation of the {@link RemoteWebDriver} instance.
108 | */
109 | @Before
110 | public void setUp() throws Exception {
111 | DesiredCapabilities capabilities = new DesiredCapabilities();
112 |
113 | capabilities.setCapability(CapabilityType.BROWSER_NAME, browser);
114 | capabilities.setCapability(CapabilityType.VERSION, version);
115 | capabilities.setCapability("deviceName", deviceName);
116 | capabilities.setCapability("device-orientation", deviceOrientation);
117 | capabilities.setCapability(CapabilityType.PLATFORM, os);
118 |
119 | String methodName = name.getMethodName();
120 | capabilities.setCapability("name", methodName);
121 |
122 | //Getting the build name.
123 | //Using the Jenkins ENV var. You can use your own. If it is not set test will run without a build id.
124 | if (buildTag != null) {
125 | capabilities.setCapability("build", buildTag);
126 | }
127 | this.driver = new RemoteWebDriver(
128 | new URL("https://" + username+ ":" + accesskey + seleniumURI +"/wd/hub"),
129 | capabilities);
130 |
131 | this.sessionId = (((RemoteWebDriver) driver).getSessionId()).toString();
132 | }
133 |
134 | @After
135 | public void tearDown() throws Exception {
136 | driver.quit();
137 | }
138 |
139 | /**
140 | * @return the value of the Sauce Job id.
141 | */
142 | @Override
143 | public String getSessionId() {
144 | return sessionId;
145 | }
146 |
147 | @BeforeClass
148 | public static void setupClass() {
149 | //get the uri to send the commands to.
150 | seleniumURI = "@ondemand.saucelabs.com:443";
151 | //If available add build tag. When running under Jenkins BUILD_TAG is automatically set.
152 | //You can set this manually on manual runs.
153 | buildTag = System.getenv("BUILD_TAG");
154 | if (buildTag == null) {
155 | buildTag = System.getenv("SAUCE_BUILD_NAME");
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------