Skip to content

Commit f2b9052

Browse files
Merge pull request #1 from RohanImmanuel/develop
repo init
2 parents a6eabd4 + 12d1a55 commit f2b9052

File tree

9 files changed

+431
-2
lines changed

9 files changed

+431
-2
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea/
2+
.classpath
3+
.project
4+
.settings/
5+
target/
6+
browserstack.err

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,35 @@
1-
# java-playwright-browserstack
2-
Creating a sample repo for different Playwright languages and runners
1+
## java-playwright-browserstack
2+
3+
## Setup
4+
* Clone the repo
5+
* Install dependencies `mvn install`
6+
* Update credentials in the `/src/test/resources/*.conf.json` file with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings).
7+
* For parallel testing, control the concurrency by setting the value for `parallel.count`. Junit 5 uses the following properties for parallelism:
8+
```
9+
junit.jupiter.execution.parallel.enabled = true
10+
junit.jupiter.execution.parallel.mode.default = concurrent
11+
junit.jupiter.execution.parallel.config.strategy=fixed
12+
junit.jupiter.execution.parallel.config.fixed.parallelism=${parallel.count}
13+
```
14+
## Running your tests
15+
* To run a sample tests, run `mvn test -P sample-test`
16+
* To run sample tests with local, run `mvn test -P sample-local-test`
17+
* Update `<parallel.count>` in `pom.xml` to set the number of parallel threads
18+
19+
Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github)
20+
21+
## Notes
22+
* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
23+
* You can export the environment variables for the Username and Access Key of your BrowserStack account.
24+
25+
* For Unix-like or Mac machines:
26+
```
27+
export BROWSERSTACK_USERNAME=<browserstack-username> &&
28+
export BROWSERSTACK_ACCESS_KEY=<browserstack-access-key>
29+
```
30+
31+
* For Windows:
32+
```
33+
set BROWSERSTACK_USERNAME=<browserstack-username>
34+
set BROWSERSTACK_ACCESS_KEY=<browserstack-access-key>
35+
```

browserstack.err

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[object Object]

pom.xml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<groupId>org.example</groupId>
6+
<artifactId>Junit5Basics</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<properties>
9+
<maven.compiler.source>8</maven.compiler.source>
10+
<maven.compiler.target>8</maven.compiler.target>
11+
<junit-jupiter-engine>5.8.1</junit-jupiter-engine>
12+
<junit-vintage-engine>5.4.0</junit-vintage-engine>
13+
<json-simple>1.1</json-simple>
14+
<selenium-java>4.1.0</selenium-java>
15+
<maven-surefire-plugin>3.0.0-M5</maven-surefire-plugin>
16+
<browserstack-local-java>1.0.6</browserstack-local-java>
17+
<httpclient>4.5.13</httpclient>
18+
<parallel.count>3</parallel.count>
19+
<tests.single>**/tests.SampleTest.java</tests.single>
20+
</properties>
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.junit.jupiter</groupId>
24+
<artifactId>junit-jupiter-engine</artifactId>
25+
<version>${junit-jupiter-engine}</version>
26+
<scope>test</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.junit.vintage</groupId>
30+
<artifactId>junit-vintage-engine</artifactId>
31+
<version>${junit-vintage-engine}</version>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>com.microsoft.playwright</groupId>
36+
<artifactId>playwright</artifactId>
37+
<version>1.19.0</version>
38+
<scope>compile</scope>
39+
</dependency>
40+
<dependency>
41+
<groupId>com.googlecode.json-simple</groupId>
42+
<artifactId>json-simple</artifactId>
43+
<version>${json-simple}</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.seleniumhq.selenium</groupId>
47+
<artifactId>selenium-java</artifactId>
48+
<version>${selenium-java}</version>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.apache.maven.plugins</groupId>
52+
<artifactId>maven-surefire-plugin</artifactId>
53+
<version>${maven-surefire-plugin}</version>
54+
<type>maven-plugin</type>
55+
</dependency>
56+
<dependency>
57+
<groupId>com.browserstack</groupId>
58+
<artifactId>browserstack-local-java</artifactId>
59+
<version>${browserstack-local-java}</version>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.apache.httpcomponents</groupId>
63+
<artifactId>httpclient</artifactId>
64+
<version>${httpclient}</version>
65+
</dependency>
66+
</dependencies>
67+
<profiles>
68+
<profile>
69+
<id>sample-local-test</id>
70+
<build>
71+
<plugins>
72+
<plugin>
73+
<groupId>org.apache.maven.plugins</groupId>
74+
<artifactId>maven-surefire-plugin</artifactId>
75+
<version>3.0.0-M5</version>
76+
<configuration>
77+
<includes>
78+
<include>${tests.single}</include>
79+
</includes>
80+
<systemPropertyVariables>
81+
<config>browserstack.conf.json</config>
82+
<local>true</local>
83+
</systemPropertyVariables>
84+
<properties>
85+
<configurationParameters>
86+
junit.jupiter.execution.parallel.enabled = true
87+
junit.jupiter.execution.parallel.mode.default = concurrent
88+
junit.jupiter.execution.parallel.config.strategy=fixed
89+
junit.jupiter.execution.parallel.config.fixed.parallelism=${parallel.count}
90+
</configurationParameters>
91+
</properties>
92+
<testFailureIgnore>false</testFailureIgnore>
93+
</configuration>
94+
</plugin>
95+
</plugins>
96+
</build>
97+
</profile>
98+
<profile>
99+
<id>sample-test</id>
100+
<build>
101+
<plugins>
102+
<plugin>
103+
<groupId>org.apache.maven.plugins</groupId>
104+
<artifactId>maven-surefire-plugin</artifactId>
105+
<version>3.0.0-M5</version>
106+
<configuration>
107+
<includes>
108+
<include>${tests.single}</include>
109+
</includes>
110+
<systemPropertyVariables>
111+
<config>browserstack.conf.json</config>
112+
<local>false</local>
113+
</systemPropertyVariables>
114+
<properties>
115+
<configurationParameters>
116+
junit.jupiter.execution.parallel.enabled = true
117+
junit.jupiter.execution.parallel.mode.default = concurrent
118+
junit.jupiter.execution.parallel.config.strategy=fixed
119+
junit.jupiter.execution.parallel.config.fixed.parallelism=${parallel.count}
120+
</configurationParameters>
121+
</properties>
122+
<testFailureIgnore>false</testFailureIgnore>
123+
</configuration>
124+
</plugin>
125+
</plugins>
126+
</build>
127+
</profile>
128+
</profiles>
129+
</project>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package runners;
2+
3+
import com.microsoft.playwright.Browser;
4+
import com.microsoft.playwright.BrowserType;
5+
import com.microsoft.playwright.Playwright;
6+
import org.json.simple.JSONArray;
7+
import org.json.simple.JSONObject;
8+
import org.json.simple.parser.JSONParser;
9+
import org.junit.jupiter.api.extension.*;
10+
import utils.SetupLocalTesting;
11+
12+
import java.io.FileReader;
13+
import java.io.UnsupportedEncodingException;
14+
import java.net.URLEncoder;
15+
import java.util.*;
16+
import java.util.stream.Stream;
17+
18+
public class BstackRunner implements TestTemplateInvocationContextProvider {
19+
public Browser browser;
20+
public String username, accessKey, wss;
21+
private JSONObject mainConfig;
22+
private JSONArray platformConfig;
23+
private Map<String, Object> commonCapsConfig;
24+
25+
26+
public BstackRunner() {
27+
this.username = setupCredsAndServer().get("username");
28+
this.accessKey = setupCredsAndServer().get("accesskey");
29+
this.wss = setupCredsAndServer().get("wss");
30+
}
31+
32+
public HashMap<String, String> setupCredsAndServer() {
33+
try {
34+
if (System.getProperty("config") != null) {
35+
JSONParser parser = new JSONParser();
36+
mainConfig = (JSONObject) parser
37+
.parse(new FileReader("src/test/resources/conf/" + System.getProperty("config")));
38+
}
39+
wss = (String) mainConfig.get("wss");
40+
username = System.getenv("BROWSERSTACK_USERNAME");
41+
if (username == null) {
42+
username = (String) mainConfig.get("userName");
43+
}
44+
accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
45+
if (accessKey == null) {
46+
accessKey = (String) mainConfig.get("accessKey");
47+
}
48+
} catch (Exception e) {
49+
System.out.println(e.getMessage());
50+
}
51+
HashMap<String, String> creds = new HashMap();
52+
creds.put("username", username);
53+
creds.put("accesskey", accessKey);
54+
creds.put("wss", wss);
55+
return creds;
56+
}
57+
58+
@Override
59+
public boolean supportsTestTemplate(ExtensionContext extensionContext) {
60+
return true;
61+
}
62+
63+
@Override
64+
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext extensionContext) {
65+
List<TestTemplateInvocationContext> desiredCapsInvocationContexts = new ArrayList<>();
66+
67+
try {
68+
platformConfig = (JSONArray) mainConfig.get("environments");
69+
commonCapsConfig = (Map<String, Object>) mainConfig.get("capabilities");
70+
71+
for (int i = 0; i < platformConfig.size(); i++) {
72+
JSONObject platform = (JSONObject) platformConfig.get(i);
73+
platform.putAll(commonCapsConfig);
74+
platform.put("browserstack.username", username);
75+
platform.put("browserstack.accessKey", accessKey);
76+
if(Objects.equals(System.getProperty("local"), "true")) {
77+
platform.put("browserstack.local", "true");
78+
HashMap<String, String> localOptions = new HashMap<>();
79+
localOptions.put("key", accessKey);
80+
//Add more local options here, e.g. forceLocal, localIdentifier, etc.
81+
SetupLocalTesting.createInstance(localOptions);
82+
}
83+
desiredCapsInvocationContexts.add(invocationContext(platform));
84+
}
85+
} catch (Exception e) {
86+
e.printStackTrace();
87+
}
88+
return desiredCapsInvocationContexts.stream();
89+
}
90+
91+
private TestTemplateInvocationContext invocationContext(JSONObject capabilitiesObject) {
92+
return new TestTemplateInvocationContext() {
93+
94+
@Override
95+
public List<Extension> getAdditionalExtensions() {
96+
97+
return Collections.singletonList(new ParameterResolver() {
98+
@Override
99+
public boolean supportsParameter(ParameterContext parameterContext,
100+
ExtensionContext extensionContext) {
101+
return parameterContext.getParameter().getType().equals(Browser.class);
102+
}
103+
104+
@Override
105+
public Object resolveParameter(ParameterContext parameterContext,
106+
ExtensionContext extensionContext) {
107+
String testName = extensionContext.getTestMethod().get().getName();
108+
testName += " [" + capabilitiesObject.get("os") + " " + capabilitiesObject.get("os_version");
109+
testName += " - " + capabilitiesObject.get("browser") + " " + capabilitiesObject.get("browser_version") + "]";
110+
capabilitiesObject.put("name", testName);
111+
Playwright playwright = Playwright.create();
112+
BrowserType browserType = playwright.chromium();
113+
String caps = null;
114+
try {
115+
caps = URLEncoder.encode(capabilitiesObject.toString(), "utf-8");
116+
} catch (UnsupportedEncodingException e) {
117+
throw new RuntimeException(e);
118+
}
119+
String ws_endpoint = wss + "?caps=" + caps;
120+
browser = browserType.connect(ws_endpoint);
121+
return browser;
122+
}
123+
});
124+
}
125+
};
126+
}
127+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package runners;
2+
3+
import org.apiguardian.api.API;
4+
import org.junit.jupiter.api.TestTemplate;
5+
import org.junit.jupiter.api.extension.ExtendWith;
6+
import org.junit.platform.commons.annotation.Testable;
7+
8+
import java.lang.annotation.*;
9+
10+
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
11+
@Retention(RetentionPolicy.RUNTIME)
12+
@Documented
13+
@API(status = API.Status.STABLE)
14+
@TestTemplate
15+
@Testable
16+
@ExtendWith(BstackRunner.class)
17+
public @interface PlaywrightTest {
18+
}

src/test/java/tests/SampleTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package tests;
2+
3+
import com.microsoft.playwright.Browser;
4+
import com.microsoft.playwright.Page;
5+
import runners.PlaywrightTest;
6+
7+
public class SampleTest {
8+
9+
@PlaywrightTest
10+
void sampleTest(Browser browser) {
11+
Page page = browser.newPage();
12+
try {
13+
page.navigate("https://bstackdemo.com/");
14+
String product_name = page.locator("//*[@id='1']/p").textContent();
15+
page.locator("//*[@id='1']/div[4]").click();
16+
page.locator(".float\\-cart__content");
17+
String product_in_cart = page.locator("//*[@id='__next']/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]").textContent();
18+
// Update Test Status
19+
if (product_name.equals(product_in_cart)) {
20+
page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + "passed" + "\", \"reason\": \"" + "Product has been successfully added to the cart!" + "\"}}");
21+
} else {
22+
page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + "failed" + "\", \"reason\": \"" + "There was some issue!" + "\"}}");
23+
}
24+
} catch (Exception e) {
25+
page.evaluate("_ => {}", "browserstack_executor: { \"action\": \"setSessionStatus\", \"arguments\": { \"status\": \"" + "failed" + "\", \"reason\": \"" + "There was some issue!" + "\"}}");
26+
System.out.println("Exception: " + e.getMessage());
27+
}
28+
browser.close();
29+
}
30+
}

0 commit comments

Comments
 (0)