Skip to content

Commit 3d134ab

Browse files
Adding support for Samsung Browser and MS Edge (#17)
* Fix Brave script * Adding support for Samsung Browser and MS Edge * Adding support for Samsung Browser and MS Edge * update readme * update readme * Adding support for Samsung Browser and MS Edge * edge
1 parent 37e403b commit 3d134ab

7 files changed

Lines changed: 442 additions & 110 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ LOCAL_PROTOCOL=true appium server -pa /wd/hub --use-drivers=cdp-driver
3030

3131
### Appium Capabilities
3232

33-
| Capability | Required | Type | Description |
34-
| ----------------------- | :------: | :----: | ------------------------------------------------------------------- |
35-
| `appium:automationName` | + | string | Must be `CDP` |
36-
| `appium:browserName` | + | string | Must be `chrome` or `Terrace` or `opera` or `brave` or `duckduckgo` |
33+
| Capability | Required | Type | Description |
34+
| ----------------------- | :------: | :----: | --------------------------------------------------------------------------------------- |
35+
| `appium:automationName` | + | string | Must be `CDP` |
36+
| `appium:browserName` | + | string | Must be one of [`chrome`, `Terrace`, `opera`, `brave`, `duckduckgo`, `samsung`, `edge`] |
3737

3838
### W3C Capabilities
3939

package-lock.json

Lines changed: 103 additions & 103 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"appium",
66
"chrome-dev-tools"
77
],
8-
"version": "1.0.4",
8+
"version": "1.0.5",
99
"author": "",
1010
"license": "Apache-2.0",
1111
"repository": {
@@ -34,7 +34,9 @@
3434
"scripts": {
3535
"skip-welcome-opera": "./build/scripts/opera.js",
3636
"skip-welcome-brave": "./build/scripts/brave.js",
37-
"skip-welcome-duckduckgo": "./build/scripts/duckduckgo.js"
37+
"skip-welcome-duckduckgo": "./build/scripts/duckduckgo.js",
38+
"skip-welcome-samsung": "./build/scripts/samsung.js",
39+
"skip-welcome-edge": "./build/scripts/edge.js"
3840
}
3941
},
4042
"scripts": {

scripts/brave.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ const common = {
2020
async function skipWelcomeBrave() {
2121
const adb = await ADB.createADB();
2222
await adb.adbExec(['shell', 'pm', 'clear', 'com.brave.browser']);
23-
//await adb.startApp(Object.assign({}, opera, common));
2423
const driver = new AndroidUiautomator2Driver();
2524
const caps = {
2625
platformName: "Android",

scripts/edge.js

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#!/usr/bin/env node
2+
3+
import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
4+
import { ADB } from 'appium-adb';
5+
import log from '../src/logger.js';
6+
import { waitForCondition } from 'asyncbox';
7+
8+
const START_APP_WAIT_DURATION = 60000;
9+
10+
const edge = {
11+
pkg: 'com.microsoft.emmx',
12+
activity: 'com.microsoft.ruby.Main',
13+
};
14+
15+
const common = {
16+
waitDuration: START_APP_WAIT_DURATION,
17+
optionalIntentArguments: '-d www.appium.io',
18+
};
19+
20+
async function skipWelcomeEdge() {
21+
const adb = await ADB.createADB();
22+
await adb.adbExec(['shell', 'pm', 'clear', edge.pkg]);
23+
const driver = new AndroidUiautomator2Driver();
24+
const caps = {
25+
platformName: "Android",
26+
"appium:automationName": "UiAutomator2",
27+
"appium:deviceName": "Android Device",
28+
"appium:appPackage": edge.pkg,
29+
"appium:appActivity": edge.activity,
30+
};
31+
32+
const findElementWithWaitForCondition = async (
33+
strategy,
34+
selector,
35+
timeout = 6000
36+
) => {
37+
try {
38+
return await waitForCondition(
39+
async () => {
40+
try {
41+
log.info(
42+
`Attempting to find element (${strategy}: ${selector})`
43+
);
44+
const element = await driver.findElement(strategy, selector);
45+
log.info(
46+
`Successfully found element (${strategy}: ${selector})`
47+
);
48+
return element;
49+
} catch (error) {
50+
// Return false to continue waiting
51+
return false;
52+
}
53+
},
54+
{
55+
waitMs: timeout,
56+
intervalMs: 1000,
57+
}
58+
);
59+
} catch (error) {
60+
throw new Error(
61+
`Failed to find element (${strategy}: ${selector}) within ${timeout}ms timeout: ${error.message}`
62+
);
63+
}
64+
};
65+
66+
67+
try {
68+
await driver.createSession(null, {
69+
alwaysMatch: caps,
70+
firstMatch: [{}],
71+
});
72+
const activity = await driver.getCurrentActivity();
73+
log.info(`Activity is ${activity}`);
74+
if (activity.includes('MicrosoftFirstRunActivity')) {
75+
// wait for the page to load
76+
await new Promise(resolve => setTimeout(resolve, 5000));
77+
78+
const MAX_RETRIES = 3;
79+
let attempt = 0;
80+
let clicked = false;
81+
let found = false;
82+
var notNowButton;
83+
84+
while (attempt < MAX_RETRIES && !clicked) {
85+
try{
86+
notNowButton = await findElementWithWaitForCondition(
87+
'xpath',
88+
'//android.widget.Button[@text="Not now"]'
89+
);
90+
log.info(`Not Now button is ${JSON.stringify(notNowButton, null, 2)}`);
91+
found = true;
92+
} catch(error) {
93+
log.info(`Not Now button not found, retrying ...`);
94+
} finally {
95+
if (found) {
96+
await driver.click(notNowButton.ELEMENT);
97+
clicked = true;
98+
}
99+
attempt++;
100+
}
101+
}
102+
103+
attempt = 0;
104+
clicked = false;
105+
found = false;
106+
var checkBox;
107+
108+
while (attempt < MAX_RETRIES && !clicked) {
109+
try{
110+
checkBox = await findElementWithWaitForCondition(
111+
'xpath',
112+
'//android.widget.Image'
113+
);
114+
log.info(`Check box is ${JSON.stringify(checkBox, null, 2)}`);
115+
found = true;
116+
} catch(error) {
117+
log.info(`Check box not found, retrying the other xpath...`);
118+
try {
119+
checkBox = await findElementWithWaitForCondition(
120+
'xpath',
121+
'//android.widget.CheckBox[@text="Help improve Microsoft products by sending optional diagnostic data about how you use the browser, websites you visit, and crash reports."]'
122+
);
123+
log.info(`Check box is ${JSON.stringify(checkBox, null, 2)}`);
124+
found = true;
125+
} catch(error) {
126+
log.info(`Check box not found, retrying...`);
127+
}
128+
} finally {
129+
if (found) {
130+
await driver.click(checkBox.ELEMENT);
131+
clicked = true;
132+
}
133+
attempt++;
134+
}
135+
}
136+
137+
attempt = 0;
138+
clicked = false;
139+
found = false;
140+
var confirmButton;
141+
142+
while (attempt < MAX_RETRIES && !clicked) {
143+
try{
144+
confirmButton = await findElementWithWaitForCondition(
145+
'xpath',
146+
'//android.widget.Button[@text="Confirm"]'
147+
);
148+
log.info(`Confirm button is ${JSON.stringify(confirmButton, null, 2)}`);
149+
found = true;
150+
} catch(error) {
151+
log.info(`Confirm button not found, retrying...`);
152+
} finally {
153+
if (found) {
154+
await driver.click(confirmButton.ELEMENT);
155+
clicked = true;
156+
}
157+
attempt++;
158+
}
159+
}
160+
}
161+
} finally {
162+
await driver.deleteSession();
163+
}
164+
165+
try {
166+
caps["appium:noReset"] = true;
167+
await driver.createSession(null, {
168+
alwaysMatch: caps,
169+
firstMatch: [{}],
170+
});
171+
const activity = await driver.getCurrentActivity();
172+
log.info(`Activity is ${activity}`);
173+
if (activity.includes('GrantPermissionsActivity')) {
174+
// wait for the page to load
175+
await new Promise(resolve => setTimeout(resolve, 5000));
176+
177+
const MAX_RETRIES = 3;
178+
let attempt = 0;
179+
let clicked = false;
180+
let found = false;
181+
var denyButton;
182+
183+
while (attempt < MAX_RETRIES && !clicked) {
184+
try{
185+
denyButton = await findElementWithWaitForCondition(
186+
'id',
187+
'com.android.permissioncontroller:id/permission_allow_button'
188+
);
189+
log.info(`Deny button is ${JSON.stringify(denyButton, null, 2)}`);
190+
found = true;
191+
} catch(error) {
192+
log.info(`Deny button not found, retrying ...`);
193+
} finally {
194+
if (found) {
195+
await driver.click(denyButton.ELEMENT);
196+
clicked = true;
197+
}
198+
attempt++;
199+
}
200+
}
201+
}
202+
} finally {
203+
await driver.deleteSession();
204+
}
205+
206+
207+
208+
}
209+
210+
(async () => {
211+
await skipWelcomeEdge();
212+
process.exit(0);
213+
})();

scripts/samsung.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env node
2+
3+
import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver';
4+
import { ADB } from 'appium-adb';
5+
import log from '../src/logger.js';
6+
import { waitForCondition } from 'asyncbox';
7+
8+
const START_APP_WAIT_DURATION = 60000;
9+
10+
const samsung = {
11+
pkg: 'com.sec.android.app.sbrowser',
12+
activity: 'com.sec.android.app.sbrowser.SBrowserMainActivity',
13+
};
14+
15+
const common = {
16+
waitDuration: START_APP_WAIT_DURATION,
17+
optionalIntentArguments: '-d www.appium.io',
18+
};
19+
20+
async function skipWelcomeSamsung() {
21+
const adb = await ADB.createADB();
22+
await adb.adbExec(['shell', 'pm', 'clear', samsung.pkg]);
23+
const driver = new AndroidUiautomator2Driver();
24+
const caps = {
25+
platformName: "Android",
26+
"appium:automationName": "UiAutomator2",
27+
"appium:deviceName": "Android Device",
28+
"appium:appPackage": samsung.pkg,
29+
"appium:appActivity": samsung.activity,
30+
};
31+
try {
32+
await driver.createSession(null, {
33+
alwaysMatch: caps,
34+
firstMatch: [{}],
35+
});
36+
const activity = await driver.getCurrentActivity();
37+
log.info(`Activity is ${activity}`);
38+
if (activity.includes('HelpIntroActivity')) {
39+
const findElementWithWaitForCondition = async (
40+
strategy,
41+
selector,
42+
timeout = 6000
43+
) => {
44+
try {
45+
return await waitForCondition(
46+
async () => {
47+
try {
48+
log.info(
49+
`Attempting to find element (${strategy}: ${selector})`
50+
);
51+
const element = await driver.findElement(strategy, selector);
52+
log.info(
53+
`Successfully found element (${strategy}: ${selector})`
54+
);
55+
return element;
56+
} catch (error) {
57+
// Return false to continue waiting
58+
return false;
59+
}
60+
},
61+
{
62+
waitMs: timeout,
63+
intervalMs: 1000,
64+
}
65+
);
66+
} catch (error) {
67+
throw new Error(
68+
`Failed to find element (${strategy}: ${selector}) within ${timeout}ms timeout: ${error.message}`
69+
);
70+
}
71+
};
72+
73+
const MAX_RETRIES = 2;
74+
let attempt = 0;
75+
76+
while (attempt < MAX_RETRIES) {
77+
try{
78+
const buttonToClick = await findElementWithWaitForCondition(
79+
'id',
80+
'com.sec.android.app.sbrowser:id/help_intro_legal_agree_button'
81+
);
82+
log.info(`Button to click is ${JSON.stringify(buttonToClick, null, 2)}`);
83+
await driver.click(buttonToClick.ELEMENT);
84+
85+
} catch(error) {
86+
log.info(`Continue button not found, retrying...`);
87+
} finally {
88+
attempt++;
89+
}
90+
}
91+
}
92+
} finally {
93+
await driver.deleteSession();
94+
}
95+
}
96+
97+
(async () => {
98+
await skipWelcomeSamsung();
99+
process.exit(0);
100+
})();

src/adb.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const DEVTOOLS_SOCKET_MAP = {
1111
brave: 'chrome_devtools_remote',
1212
opera: 'com.opera.browser.devtools',
1313
duckduckgo: 'webview_devtools_remote',
14+
samsung: 'Terrace_devtools_remote',
15+
edge: 'chrome_devtools_remote',
1416
terrance: 'com.sec.android.app.sbrowser_devtools_remote',
1517
};
1618

@@ -112,6 +114,16 @@ export async function startApplication(browser = 'chrome') {
112114
activity: 'com.duckduckgo.app.browser.BrowserActivity',
113115
};
114116

117+
const samsung = {
118+
pkg: 'com.sec.android.app.sbrowser',
119+
activity: 'com.sec.android.app.sbrowser.SBrowserMainActivity',
120+
};
121+
122+
const edge = {
123+
pkg: 'com.microsoft.emmx',
124+
activity: 'com.microsoft.ruby.Main',
125+
};
126+
115127
if (browser === 'chrome') {
116128
log.info(`Starting Chrome`);
117129
await adb.startApp(Object.assign({}, chrome, common));
@@ -127,5 +139,11 @@ export async function startApplication(browser = 'chrome') {
127139
} else if (browser === 'duckduckgo') {
128140
log.info(`Starting DuckDuckGo`);
129141
await adb.startApp(Object.assign({}, duckduckgo, common));
142+
} else if (browser === 'samsung') {
143+
log.info(`Starting Samsung Browser`);
144+
await adb.startApp(Object.assign({}, samsung, common));
145+
} else if (browser === 'edge') {
146+
log.info(`Starting MS Edge`);
147+
await adb.startApp(Object.assign({}, edge, common));
130148
}
131149
}

0 commit comments

Comments
 (0)