Skip to content

Commit

Permalink
Merge pull request #3 from somebodysmokein/develop
Browse files Browse the repository at this point in the history
Updated with the Android config
  • Loading branch information
agrawalsaurabhs authored Aug 4, 2023
2 parents be92604 + e3bfb3f commit bd46315
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 153 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
node_modules
playwright-report
playwright-report
local.log
local.log
package-lock.json
local.log
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

- To run a sample test, run `npm run sample-test`

## Running your tests on mobile

- To run a sample test, run `npm run mobile-test`

## Run tests on locally hosted websites
* Run `npm run sample-local-test`

Expand Down
52 changes: 0 additions & 52 deletions browserstack.config.js

This file was deleted.

155 changes: 155 additions & 0 deletions fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
const base = require("@playwright/test");
const cp = require("child_process");
const { _android } = require("playwright");
const clientPlaywrightVersion = cp
.execSync("npx playwright --version")
.toString()
.trim()
.split(" ")[1];
const BrowserStackLocal = require("browserstack-local");
const util = require("util");

// BrowserStack Specific Capabilities.
// Set 'browserstack.local:true For Local testing
const caps = {
osVersion: "13.0",
deviceName: "Samsung Galaxy S23", // "Samsung Galaxy S22 Ultra", "Google Pixel 7 Pro", "OnePlus 9", etc.
browserName: "chrome",
realMobile: "true",
name: "My android playwright test",
build: "playwright-build-1",
"browserstack.username": process.env.BROWSERSTACK_USERNAME || "<USERNAME>",
"browserstack.accessKey":
process.env.BROWSERSTACK_ACCESS_KEY || "<ACCESS_KEY>",
"browserstack.local": process.env.BROWSERSTACK_LOCAL || false,
};

exports.bsLocal = new BrowserStackLocal.Local();

// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
exports.BS_LOCAL_ARGS = {
key: process.env.BROWSERSTACK_ACCESS_KEY || "ACCESSKEY",
};

// Patching the capabilities dynamically according to the project name.
const patchMobileCaps = (name, title) => {
let combination = name.split(/@browserstack/)[0];
let [browerCaps, osCaps] = combination.split(/:/);
let [browser, deviceName] = browerCaps.split(/@/);
let osCapsSplit = osCaps.split(/ /);
let os = osCapsSplit.shift();
let osVersion = osCapsSplit.join(" ");
caps.browser = browser ? browser : "chrome";
caps.deviceName = deviceName ? deviceName : "Samsung Galaxy S22 Ultra";
caps.osVersion = osVersion ? osVersion : "12.0";
caps.name = title;
caps.realMobile = "true";
};

const patchCaps = (name, title) => {
let combination = name.split(/@browserstack/)[0];
let [browerCaps, osCaps] = combination.split(/:/);
let [browser, browser_version] = browerCaps.split(/@/);
let osCapsSplit = osCaps.split(/ /);
let os = osCapsSplit.shift();
let os_version = osCapsSplit.join(" ");
caps.browser = browser ? browser : "chrome";
caps.browser_version = browser_version ? browser_version : "latest";
caps.os = os ? os : "osx";
caps.os_version = os_version ? os_version : "catalina";
caps.name = title;
};

const isHash = (entity) =>
Boolean(entity && typeof entity === "object" && !Array.isArray(entity));
const nestedKeyValue = (hash, keys) =>
keys.reduce((hash, key) => (isHash(hash) ? hash[key] : undefined), hash);
const isUndefined = (val) => val === undefined || val === null || val === "";
const evaluateSessionStatus = (status) => {
if (!isUndefined(status)) {
status = status.toLowerCase();
}
if (status === "passed") {
return "passed";
} else if (status === "failed" || status === "timedout") {
return "failed";
} else {
return "";
}
};

exports.test = base.test.extend({
page: async ({ page, playwright }, use, testInfo) => {
if (testInfo.project.name.match(/browserstack/)) {
let vBrowser, vContext, vDevice;
const isMobile = testInfo.project.name.match(/browserstack-mobile/);
if (isMobile) {
patchMobileCaps(
testInfo.project.name,
`${testInfo.file} - ${testInfo.title}`
);
vDevice = await playwright._android.connect(
`wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(
JSON.stringify(caps)
)}`
);
await vDevice.shell("am force-stop com.android.chrome");
vContext = await vDevice.launchBrowser();
} else {
patchCaps(testInfo.project.name, `${testInfo.title}`);
delete caps.osVersion;
delete caps.deviceName;
delete caps.realMobile;
vBrowser = await playwright.chromium.connect({
wsEndpoint:
`wss://cdp.browserstack.com/playwright?caps=` +
`${encodeURIComponent(JSON.stringify(caps))}`,
});
vContext = await vBrowser.newContext(testInfo.project.use);
}
const vPage = await vContext.newPage();
await use(vPage);

await vPage.close();

if (isMobile) {
await vDevice.close();
} else {
await vBrowser.close();
}
} else {
use(page);
}
},

beforeEach: [
async ({ page }, use) => {
await page
.context()
.tracing.start({ screenshots: true, snapshots: true, sources: true });
await use();
},
{ auto: true },
],

afterEach: [
async ({ page }, use, testInfo) => {
await use();
if (testInfo.status == "failed") {
await page
.context()
.tracing.stop({ path: `${testInfo.outputDir}/trace.zip` });
await page.screenshot({ path: `${testInfo.outputDir}/screenshot.png` });
await testInfo.attach("screenshot", {
path: `${testInfo.outputDir}/screenshot.png`,
contentType: "image/png",
});
await testInfo.attach("trace", {
path: `${testInfo.outputDir}/trace.zip`,
contentType: "application/zip",
});
}
},
{ auto: true },
],
});
40 changes: 22 additions & 18 deletions global-setup.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
// global-setup.js
const { bsLocal, BS_LOCAL_ARGS } = require('./browserstack.config');
const { promisify } = require('util');
const { bsLocal, BS_LOCAL_ARGS } = require("./fixture");
const { promisify } = require("util");
const sleep = promisify(setTimeout);
const redColour = '\x1b[31m';
const whiteColour = '\x1b[0m';
const redColour = "\x1b[31m";
const whiteColour = "\x1b[0m";
module.exports = async () => {
console.log('Starting BrowserStackLocal ...');
// Starts the Local instance with the required arguments
let localResponseReceived = false;
bsLocal.start(BS_LOCAL_ARGS, (err) => {
if (err) {
console.error(
`${redColour}Error starting BrowserStackLocal${whiteColour}`
);
} else {
console.log('BrowserStackLocal Started');
if (process.env.BROWSERSTACK_LOCAL === "true") {
console.log("Starting BrowserStackLocal ...");
// Starts the Local instance with the required arguments
let localResponseReceived = false;
bsLocal.start(BS_LOCAL_ARGS, (err) => {
if (err) {
console.error(
`${redColour}Error starting BrowserStackLocal${whiteColour}`
);
} else {
console.log("BrowserStackLocal Started");
}
localResponseReceived = true;
});
while (!localResponseReceived) {
await sleep(1000);
}
localResponseReceived = true;
});
while (!localResponseReceived) {
await sleep(1000);
} else {
console.log("Skipping BrowserStackLocal...");
}
};
8 changes: 4 additions & 4 deletions global-teardown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// global-teardown.js
const { bsLocal } = require('./browserstack.config');
const { promisify } = require('util');
const { bsLocal } = require("./fixture");
const { promisify } = require("util");
const sleep = promisify(setTimeout);
module.exports = async () => {
// Stop the Local instance after your test run is completed, i.e after driver.quit
Expand All @@ -9,10 +9,10 @@ module.exports = async () => {
if (bsLocal && bsLocal.isRunning()) {
bsLocal.stop(() => {
localStopped = true;
console.log('Stopped BrowserStackLocal');
console.log("Stopped BrowserStackLocal");
});
while (!localStopped) {
await sleep(1000);
}
}
}
};
Binary file added local.log
Binary file not shown.
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
"description": "",
"main": "index.js",
"scripts": {
"sample-local-test":"npx playwright test tests/local_test.js",
"sample-test":"npx playwright test tests/sample_test.js"
"sample-local-test": "BROWSERSTACK_LOCAL=true npx playwright test tests/local_test.js",
"sample-test": "npx playwright test tests/sample_test.js",
"mobile-test": "npx playwright test tests/sample_test.js --project='chrome@Samsung Galaxy S22:13@browserstack-mobile'"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@playwright/test": "^1.29.1",
"browserstack-local": "^1.5.1"
"@playwright/test": "^1.34.3",
"browserstack-local": "^1.5.1",
"playwright": "1.34.3",
"prettier": "2.8.8"
}
}
Loading

0 comments on commit bd46315

Please sign in to comment.