API are only available on the chrome://version page. It allows the use of tools such as Browserstack for test automation. Do not activate the corresponding options (available in the developer settings) if you do not know what you are doing.
338 lines
9.6 KiB
JavaScript
338 lines
9.6 KiB
JavaScript
const { remote } = require('webdriverio');
|
|
const { bootstrap } = require('global-agent');
|
|
const path = require('node:path');
|
|
const fs = require('node:fs/promises');
|
|
const { appendFile } = require('node:fs');
|
|
const { count } = require('node:console');
|
|
|
|
// export GLOBAL_AGENT_HTTP_PROXY=$HTTPS_PROXY
|
|
bootstrap();
|
|
|
|
let driver;
|
|
|
|
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
const click = async el => {
|
|
try {
|
|
const x = await driver.$(el);
|
|
await x.click();
|
|
return true;
|
|
}
|
|
catch {
|
|
return false;
|
|
}
|
|
}
|
|
const clickByUIautomator = async el => {
|
|
const x = await driver.$("-android uiautomator:" + el);
|
|
await x.click();
|
|
return x;
|
|
}
|
|
const pressBack = async times => {
|
|
for (let t = 0; t < times; t++)
|
|
await driver.executeScript("mobile: pressKey", [{ "keycode": 4 }]); // BACK
|
|
}
|
|
const downFor = async times => {
|
|
for (let t = 0; t < times; t++)
|
|
await driver.executeScript("mobile: pressKey", [{ "keycode": 20 }]); // DOWN
|
|
}
|
|
const goto = async (selectorKey, url) => {
|
|
let el4 = await clickByUIautomator(
|
|
'new UiSelector().resourceId("' + selectorKey + ':id/url_bar")');
|
|
await el4.addValue(url);
|
|
await clickByUIautomator(
|
|
'new UiSelector().resourceId("' + selectorKey + ':id/line_1")');
|
|
}
|
|
|
|
function MakePath(config, file) {
|
|
return path.join(
|
|
config.outputFolder,
|
|
config.deviceName.replaceAll(' ', '_'),
|
|
file
|
|
)
|
|
}
|
|
|
|
// driver.addCommand('sendCommandFromWebSocket', command('POST', '/session/:sessionId/chromium/send_command', {
|
|
// command: 'sendCommandFromWebSocket',
|
|
// description: 'sendCommandFromWebSocket chromium command',
|
|
// ref: 'https://vendor.com/commands/#myNewCommand',
|
|
// // variables: [{
|
|
// // name: 'someId',
|
|
// // description: 'some id to something'
|
|
// // }],
|
|
// parameters: [{
|
|
// name: 'method',
|
|
// type: 'string',
|
|
// description: 'a valid parameter',
|
|
// required: true
|
|
// }, {
|
|
// name: 'params',
|
|
// type: 'object',
|
|
// description: 'a valid parameter',
|
|
// required: true
|
|
// }, {
|
|
// name: 'id',
|
|
// type: 'number',
|
|
// description: 'a valid parameter',
|
|
// required: true
|
|
// }]
|
|
// }))
|
|
// await driver.sendCommandFromWebSocket("lll", {}, -1);
|
|
|
|
async function testApp(isLocal, config) {
|
|
console.log("Starting");
|
|
|
|
const logDirectory = MakePath(config, "");
|
|
try {
|
|
await fs.mkdir(logDirectory, { recursive: true });
|
|
} catch {
|
|
if (!config.skipCheckDirectory) {
|
|
console.log("Directory " + logDirectory + " already exists.");
|
|
process.exit(0);
|
|
}
|
|
}
|
|
|
|
let selectorKey = "org.cromite.cromite";
|
|
let isChromium = false;
|
|
if (config.appName == "chromium") {
|
|
selectorKey = "org.chromium.chrome"; //.stable"; //"org.chromium.chrome";
|
|
isChromium = true;
|
|
}
|
|
|
|
const capabilities_local = {
|
|
platformName: 'android',
|
|
'appium:automationName': 'UiAutomator2',
|
|
'appium:appPackage': selectorKey,
|
|
'appium:appActivity': 'com.google.android.apps.chrome.Main',
|
|
|
|
'appium:showChromedriverLog': true,
|
|
//'appium:recreateChromeDriverSessions': true,
|
|
|
|
'appium:chromeOptions': {
|
|
'androidDeviceSocket': 'chrome_devtools_remote', // cat /proc/net/unix
|
|
'androidExecName': 'unusedbutimportant',
|
|
},
|
|
};
|
|
|
|
const capabilities_bs = {
|
|
"platformName": "android",
|
|
|
|
"appium:deviceName": config.deviceName,
|
|
"appium:app": config.appName,
|
|
|
|
'bstack:options': {
|
|
"appiumVersion": "2.4.1",
|
|
"disableAnimations": "true",
|
|
"userName": config.BROWSERSTACK_USERNAME,
|
|
"accessKey": config.BROWSERSTACK_ACCESS_KEY,
|
|
},
|
|
|
|
// Set other BrowserStack capabilities
|
|
// 'project' : 'First NodeJS project',
|
|
// 'build' : 'Node Android',
|
|
// 'name': 'first_test',
|
|
// 'unicodeKeyboard': 'true',
|
|
// 'resetKeyboard': 'true',
|
|
};
|
|
|
|
if (!isLocal) {
|
|
driver = await remote({
|
|
capabilities: capabilities_bs,
|
|
hostname: 'hub-cloud.browserstack.com',
|
|
path: '/wd/hub',
|
|
protocol: 'https',
|
|
port: 443,
|
|
strictSSL: true,
|
|
logLevel: 'trace',
|
|
});
|
|
} else {
|
|
driver = await remote({
|
|
capabilities: capabilities_local,
|
|
hostname: '127.0.0.1',
|
|
port: 4723,
|
|
});
|
|
}
|
|
|
|
try {
|
|
const info = await driver.executeScript("mobile: deviceInfo", [{}]);
|
|
console.log(info);
|
|
|
|
await fs.writeFile(MakePath(config, "info.json"), JSON.stringify(info));
|
|
|
|
// cromite
|
|
const terms_accept_present = await driver.findElement("id", selectorKey + ":id/terms_accept");
|
|
console.log(!terms_accept_present.error);
|
|
if (!terms_accept_present.error) {
|
|
await click("id:" + selectorKey + ":id/terms_accept");
|
|
|
|
await clickByUIautomator(
|
|
'new UiSelector().resourceId("' + selectorKey + ':id/default_search_engine_dialog_options")' +
|
|
'.childSelector(new UiSelector().className("android.widget.RadioButton"))');
|
|
|
|
await click("id:" + selectorKey + ":id/button_primary");
|
|
}
|
|
|
|
// chromium
|
|
if (isChromium) await sleep(4000);
|
|
const signin_fre_dismiss_button = await await driver.findElement("id", selectorKey + ":id/signin_fre_dismiss_button");
|
|
if (!signin_fre_dismiss_button.error) {
|
|
await click("id:" + selectorKey + ":id/signin_fre_dismiss_button");
|
|
}
|
|
else {
|
|
const signin_fre_continue_button = await await driver.findElement("id", selectorKey + ":id/signin_fre_continue_button");
|
|
if (!signin_fre_continue_button.error) {
|
|
await click("id:" + selectorKey + ":id/signin_fre_continue_button");
|
|
}
|
|
}
|
|
|
|
// click menu
|
|
await clickByUIautomator(
|
|
'new UiSelector().resourceId("' + selectorKey + ':id/menu_button")');
|
|
await sleep(1000);
|
|
|
|
// click on preferences
|
|
if (!await click("id:" + selectorKey + ":id/preferences_id")) {
|
|
await driver.executeScript("mobile:flingGesture",
|
|
[{ "left": 400, "top": 100, "width": 200, "height": 200, "direction": "down" }]);
|
|
await click("id:" + selectorKey + ":id/preferences_id");
|
|
}
|
|
await sleep(1000);
|
|
|
|
// disable adblock
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Adblock Plus settings")');
|
|
await sleep(1000);
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Enable Adblock Plus")');
|
|
|
|
// go back on preferences
|
|
await pressBack(1);
|
|
await sleep(1000);
|
|
|
|
// move preferences layout
|
|
if (!await driver.executeScript("mobile:flingGesture",
|
|
[{ "left": 100, "top": 100, "width": 200, "height": 400, "direction": "down" }])) {
|
|
await downFor(20);
|
|
}
|
|
await sleep(1000);
|
|
|
|
// click on developer options
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Developer options")');
|
|
|
|
// enable cromite test pref
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Enable support for cromite test")');
|
|
|
|
// enable webview mode (only if chromium or is local)
|
|
if (!isLocal && !isChromium) {
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Enable webview support for cromite test")');
|
|
}
|
|
|
|
// enable pixel perfect mode
|
|
await clickByUIautomator(
|
|
'new UiSelector().text("Pixel Perfect Mode")');
|
|
|
|
// restart cromite
|
|
await clickByUIautomator(
|
|
'new UiSelector().resourceId("' + selectorKey + ':id/snackbar_button")');
|
|
await sleep(2000);
|
|
|
|
// wait for restart
|
|
let count = 0;
|
|
while ((await driver.findElement("id", selectorKey + ":id/url_bar")).error) {
|
|
await sleep(1000);
|
|
count++;
|
|
if (count > 10) break;
|
|
}
|
|
|
|
// open chrome://version
|
|
await goto(selectorKey, "chrome://version");
|
|
|
|
// change the context
|
|
let contexts = await driver.getContexts();
|
|
console.log(contexts);
|
|
|
|
if (!isLocal && !isChromium) {
|
|
await driver.switchContext('WEBVIEW_' + selectorKey);
|
|
} else {
|
|
await driver.switchContext('WEBVIEW_chrome');
|
|
}
|
|
|
|
contexts = await driver.getContexts();
|
|
console.log(contexts);
|
|
|
|
// start update of cromite fonts pack
|
|
await driver.executeScript(
|
|
'await window.cromite.startComponentUpdate("gcmjkmgdlgnkkcocmoeiminaijmmjnii")', []);
|
|
|
|
count = 0;
|
|
for (; ;) {
|
|
let version = await driver.executeScript(
|
|
'return JSON.parse(await window.cromite.getComponentData("gcmjkmgdlgnkkcocmoeiminaijmmjnii")).version;', []);
|
|
console.log(version);
|
|
if (version != "0.0.0.0") break;
|
|
|
|
count++;
|
|
if (count > 20) break;
|
|
await sleep(10000);
|
|
}
|
|
|
|
// open creepjs
|
|
await driver.executeScript('window.location.href="https://abrahamjuliot.github.io/creepjs"', []);
|
|
if (!isLocal)
|
|
await sleep(10000);
|
|
else
|
|
await sleep(30000);
|
|
|
|
// get creepjs json
|
|
let creep = await driver.executeScript("return JSON.stringify(window.Creep);", []);
|
|
await fs.writeFile(MakePath(config, "creep.json"), creep);
|
|
|
|
let fingerprint = await driver.executeScript("return JSON.stringify(window.Fingerprint);", []);
|
|
await fs.writeFile(MakePath(config, "fingerprint.json"), fingerprint);
|
|
} finally {
|
|
await driver.deleteSession();
|
|
driver = undefined;
|
|
}
|
|
}
|
|
|
|
if (process.argv.length <= 3) {
|
|
console.error('Args:');
|
|
console.error(' [local|bs] running environment');
|
|
console.error(' [devicename] device');
|
|
console.error(' [app name] bs device name');
|
|
process.exit(1);
|
|
}
|
|
|
|
if (process.env.BROWSERSTACK_OUTPUT_FOLDER === undefined) {
|
|
console.error('set BROWSERSTACK_OUTPUT_FOLDER env variable');
|
|
process.exit(1);
|
|
}
|
|
|
|
let isLocal = process.argv[2] === 'local';
|
|
if (!isLocal) {
|
|
if (process.env.BROWSERSTACK_USERNAME === undefined) {
|
|
console.error('set BROWSERSTACK_USERNAME env variable');
|
|
process.exit(1);
|
|
}
|
|
if (process.env.BROWSERSTACK_ACCESS_KEY === undefined) {
|
|
console.error('set BROWSERSTACK_ACCESS_KEY env variable');
|
|
process.exit(1);
|
|
}
|
|
testApp(/*isLocal*/ false, {
|
|
deviceName: process.argv[3],
|
|
appName: process.argv[4],
|
|
BROWSERSTACK_USERNAME: process.env.BROWSERSTACK_USERNAME,
|
|
BROWSERSTACK_ACCESS_KEY: process.env.BROWSERSTACK_ACCESS_KEY,
|
|
outputFolder: process.env.BROWSERSTACK_OUTPUT_FOLDER,
|
|
skipCheckDirectory: false,
|
|
});
|
|
} else {
|
|
testApp(/*isLocal*/ true, {
|
|
deviceName: process.argv[3],
|
|
appName: process.argv[4],
|
|
outputFolder: process.env.BROWSERSTACK_OUTPUT_FOLDER,
|
|
skipCheckDirectory: true,
|
|
});
|
|
}
|