Skip to content

Commit 7ece018

Browse files
authored
Merge pull request #5 from browserstack/TM-1928
playwright
2 parents 084d376 + 14387a7 commit 7ece018

File tree

12 files changed

+4833
-0
lines changed

12 files changed

+4833
-0
lines changed

playwright-test/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Testing with playwright-browserstack in Test Runner
2+
3+
[Playwright](https://playwright.dev/) Integration with BrowserStack.
4+
5+
![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780)
6+
7+
## Setup
8+
9+
* Clone the repo and run `cd playwright-test`
10+
* Run `npm install`
11+
12+
## Running your tests
13+
14+
- To run a single test, run `npm test`
15+
16+
### Run sample test on privately hosted websites
17+
18+
**Using Command-line Interface**
19+
1. You have to download the BrowserStack Local binary from the links below (depending on your environment):
20+
* [OS X (10.7 and above)](https://www.browserstack.com/browserstack-local/BrowserStackLocal-darwin-x64.zip)
21+
* [Linux 32-bit](https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-ia32.zip)
22+
* [Linux 64-bit](https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip)
23+
* [Windows (XP and above)](https://www.browserstack.com/browserstack-local/BrowserStackLocal-win32.zip)
24+
2. Once you have downloaded and unzipped the file, you can initiate the binary by running the command: `./BrowserStackLocal --key YOUR_ACCESS_KEY`
25+
3. Once you see the terminal say "[SUCCESS]" You can now access your local server(s) in our remote browser”, your local testing connection is considered established.
26+
4. You can then run the sample Local test using `npm run test:local`
27+
5. To generate JUnit-XML report, run the sample Local test using - `npm run test:report`
28+
6. Direct Command to generate JUnit-XML report, run the sample Local test using - PLAYWRIGHT_JUNIT_OUTPUT_NAME=results.xml npx playwright test --config=./playwright-local.config.js --reporter=junit
29+
7. results.xml is the name of the Junit-XML which will be geenrated
30+
31+
Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github)
32+
33+
34+
## Notes
35+
* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
36+
37+
## Additional Resources
38+
* [Documentation for writing Automate test scripts with BrowserStack](https://www.browserstack.com/docs/automate/playwright)
39+
40+
## To Generate Report
41+
* [Documentation for writing Automate test scripts with BrowserStack](https://www.browserstack.com/docs/automate/playwright)

playwright-test/browserstack.err

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

playwright-test/fixtures.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const base = require('@playwright/test');
2+
const cp = require('child_process');
3+
const clientPlaywrightVersion = cp
4+
.execSync('npx playwright --version')
5+
.toString()
6+
.trim()
7+
.split(' ')[1];
8+
const BrowserStackLocal = require('browserstack-local');
9+
10+
// BrowserStack Specific Capabilities.
11+
const caps = {
12+
browser: 'chrome',
13+
os: 'osx',
14+
os_version: 'catalina',
15+
name: 'My first playwright test',
16+
build: 'playwright-build-1',
17+
'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME',
18+
'browserstack.accessKey':
19+
process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',
20+
'browserstack.local': process.env.BROWSERSTACK_LOCAL || false,
21+
'client.playwrightVersion': clientPlaywrightVersion,
22+
};
23+
24+
exports.bsLocal = new BrowserStackLocal.Local();
25+
26+
// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
27+
exports.BS_LOCAL_ARGS = {
28+
key: process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY',
29+
};
30+
31+
// Patching the capabilities dynamically according to the project name.
32+
const patchCaps = (name, title) => {
33+
let combination = name.split(/@browserstack/)[0];
34+
let [browerCaps, osCaps] = combination.split(/:/);
35+
let [browser, browser_version] = browerCaps.split(/@/);
36+
let osCapsSplit = osCaps.split(/ /);
37+
let os = osCapsSplit.shift();
38+
let os_version = osCapsSplit.join(' ');
39+
caps.browser = browser ? browser : 'chrome';
40+
caps.browser_version = browser_version ? browser_version : 'latest';
41+
caps.os = os ? os : 'osx';
42+
caps.os_version = os_version ? os_version : 'catalina';
43+
caps.name = title;
44+
};
45+
46+
const isHash = (entity) => Boolean(entity && typeof(entity) === "object" && !Array.isArray(entity));
47+
const nestedKeyValue = (hash, keys) => keys.reduce((hash, key) => (isHash(hash) ? hash[key] : undefined), hash);
48+
const isUndefined = val => (val === undefined || val === null || val === '');
49+
const evaluateSessionStatus = (status) => {
50+
if (!isUndefined(status)) {
51+
status = status.toLowerCase();
52+
}
53+
if (status === "passed") {
54+
return "passed";
55+
} else if (status === "failed" || status === "timedout") {
56+
return "failed";
57+
} else {
58+
return "";
59+
}
60+
}
61+
62+
exports.test = base.test.extend({
63+
page: async ({ page, playwright }, use, testInfo) => {
64+
// Use BrowserStack Launched Browser according to capabilities for cross-browser testing.
65+
if (testInfo.project.name.match(/browserstack/)) {
66+
patchCaps(testInfo.project.name, `${testInfo.title}`);
67+
const vBrowser = await playwright.chromium.connect({
68+
wsEndpoint:
69+
`wss://cdp.browserstack.com/playwright?caps=` +
70+
`${encodeURIComponent(JSON.stringify(caps))}`,
71+
});
72+
const vContext = await vBrowser.newContext(testInfo.project.use);
73+
const vPage = await vContext.newPage();
74+
await use(vPage);
75+
const testResult = {
76+
action: 'setSessionStatus',
77+
arguments: {
78+
status: evaluateSessionStatus(testInfo.status),
79+
reason: nestedKeyValue(testInfo, ['error', 'message'])
80+
},
81+
};
82+
await vPage.evaluate(() => {},
83+
`browserstack_executor: ${JSON.stringify(testResult)}`);
84+
await vPage.close();
85+
await vBrowser.close();
86+
} else {
87+
use(page);
88+
}
89+
},
90+
});

playwright-test/global-setup.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// global-setup.js
2+
const { bsLocal, BS_LOCAL_ARGS } = require('./fixtures');
3+
const { promisify } = require('util');
4+
const sleep = promisify(setTimeout);
5+
const redColour = '\x1b[31m';
6+
const whiteColour = '\x1b[0m';
7+
module.exports = async () => {
8+
console.log('Starting BrowserStackLocal ...');
9+
// Starts the Local instance with the required arguments
10+
let localResponseReceived = false;
11+
bsLocal.start(BS_LOCAL_ARGS, (err) => {
12+
if (err) {
13+
console.error(
14+
`${redColour}Error starting BrowserStackLocal${whiteColour}`
15+
);
16+
} else {
17+
console.log('BrowserStackLocal Started');
18+
}
19+
localResponseReceived = true;
20+
});
21+
while (!localResponseReceived) {
22+
await sleep(1000);
23+
}
24+
};

playwright-test/global-teardown.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// global-teardown.js
2+
const { bsLocal } = require('./fixtures');
3+
const { promisify } = require('util');
4+
const sleep = promisify(setTimeout);
5+
module.exports = async () => {
6+
// Stop the Local instance after your test run is completed, i.e after driver.quit
7+
let localStopped = false;
8+
9+
if (bsLocal && bsLocal.isRunning()) {
10+
bsLocal.stop(() => {
11+
localStopped = true;
12+
console.log('Stopped BrowserStackLocal');
13+
});
14+
while (!localStopped) {
15+
await sleep(1000);
16+
}
17+
}
18+
};

playwright-test/local.log

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

0 commit comments

Comments
 (0)