Skip to content

Commit 0df6c6c

Browse files
Merge pull request #60 from LambdaTest/stage
Stage
2 parents 959bec1 + 977c90e commit 0df6c6c

15 files changed

+615
-230
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lambdatest/smartui-cli",
3-
"version": "2.0.9",
3+
"version": "3.0.0",
44
"description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
55
"files": [
66
"dist/**/*"

src/lib/config.ts

+3-33
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,6 @@
11
import path from 'path'
22
import fs from 'fs'
3-
import { Config, WebStaticConfig } from '../types.js'
4-
5-
export const DEFAULT_WEB_STATIC_CONFIG: WebStaticConfig = [
6-
{
7-
"name": "lambdatest-home-page",
8-
"url": "https://www.lambdatest.com",
9-
"waitForTimeout": 1000
10-
},
11-
{
12-
"name": "example-page",
13-
"url": "https://example.com/"
14-
}
15-
]
16-
17-
export const DEFAULT_CONFIG: Config = {
18-
web: {
19-
browsers: [
20-
'chrome',
21-
'firefox',
22-
'safari',
23-
'edge'
24-
],
25-
viewports: [
26-
[1920],
27-
[1366],
28-
[360],
29-
],
30-
waitForTimeout: 1000,
31-
enableJavaScript: false,
32-
}
33-
};
3+
import constants from './constants.js';
344

355
export function createConfig(filepath: string) {
366
// default filepath
@@ -50,7 +20,7 @@ export function createConfig(filepath: string) {
5020

5121
// write stringified default config options to the filepath
5222
fs.mkdirSync(path.dirname(filepath), { recursive: true });
53-
fs.writeFileSync(filepath, JSON.stringify(DEFAULT_CONFIG, null, 2) + '\n');
23+
fs.writeFileSync(filepath, JSON.stringify(constants.DEFAULT_CONFIG, null, 2) + '\n');
5424
console.log(`Created SmartUI Config: ${filepath}`);
5525
};
5626

@@ -72,6 +42,6 @@ export function createWebStaticConfig(filepath: string) {
7242

7343
// write stringified default config options to the filepath
7444
fs.mkdirSync(path.dirname(filepath), { recursive: true });
75-
fs.writeFileSync(filepath, JSON.stringify(DEFAULT_WEB_STATIC_CONFIG, null, 2) + '\n');
45+
fs.writeFileSync(filepath, JSON.stringify(constants.DEFAULT_WEB_STATIC_CONFIG, null, 2) + '\n');
7646
console.log(`Created web-static config: ${filepath}`);
7747
};

src/lib/constants.ts

+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
export default {
2+
// default configs
3+
DEFAULT_CONFIG: {
4+
web: {
5+
browsers: [
6+
'chrome',
7+
'firefox',
8+
'safari',
9+
'edge'
10+
],
11+
viewports: [
12+
[1920],
13+
[1366],
14+
[1028],
15+
],
16+
},
17+
mobile: {
18+
devices: [
19+
'iPhone 14',
20+
'Galaxy S24',
21+
],
22+
fullPage: true,
23+
orientation: 'portrait'
24+
},
25+
waitForTimeout: 1000,
26+
enableJavaScript: false,
27+
allowedHostnames: []
28+
},
29+
DEFAULT_WEB_STATIC_CONFIG: [
30+
{
31+
"name": "lambdatest-home-page",
32+
"url": "https://www.lambdatest.com",
33+
"waitForTimeout": 1000
34+
},
35+
{
36+
"name": "example-page",
37+
"url": "https://example.com/"
38+
}
39+
],
40+
41+
// browsers
42+
CHROME: 'chrome',
43+
SAFARI: 'safari',
44+
FIREFOX: 'firefox',
45+
EDGE: 'edge',
46+
EDGE_CHANNEL: 'msedge',
47+
PW_WEBKIT: 'webkit',
48+
49+
// viewports
50+
MIN_VIEWPORT_HEIGHT: 1080,
51+
52+
// mobile
53+
MOBILE_OS_ANDROID: 'android',
54+
MOBILE_OS_IOS: 'ios',
55+
MOBILE_ORIENTATION_PORTRAIT: 'portrait',
56+
MOBILE_ORIENTATION_LANDSCAPE: 'landscape',
57+
58+
// CI
59+
GITHUB_API_HOST: 'https://api.github.com',
60+
61+
SUPPORTED_MOBILE_DEVICES: {
62+
'Blackberry KEY2 LE': { os: 'android', viewport: {width: 412, height: 618}},
63+
'Galaxy A12': { os: 'android', viewport: {width: 360, height: 800}},
64+
'Galaxy A21s': { os: 'android', viewport: {width: 412, height: 915}},
65+
'Galaxy A22': { os: 'android', viewport: {width: 358, height: 857}},
66+
'Galaxy A31': { os: 'android', viewport: {width: 412, height: 915}},
67+
'Galaxy A32': { os: 'android', viewport: {width: 412, height: 915}},
68+
'Galaxy A51': { os: 'android', viewport: {width: 412, height: 915}},
69+
'Galaxy A7': { os: 'android', viewport: {width: 412, height: 846}},
70+
'Galaxy A70': { os: 'android', viewport: {width: 412, height: 915}},
71+
'Galaxy A8': { os: 'android', viewport: {width: 360, height: 740}},
72+
'Galaxy A8 Plus': { os: 'android', viewport: {width: 412, height: 846}},
73+
'Galaxy J7 Prime': { os: 'android', viewport: {width: 360, height: 640}},
74+
'Galaxy M12': { os: 'android', viewport: {width: 412, height: 915}},
75+
'Galaxy M31': { os: 'android', viewport: {width: 412, height: 892}},
76+
'Galaxy Note10': { os: 'android', viewport: {width: 412, height: 869}},
77+
'Galaxy Note10 Plus': { os: 'android', viewport: {width: 412, height: 869}},
78+
'Galaxy Note20': { os: 'android', viewport: {width: 412, height: 915}},
79+
'Galaxy Note20 Ultra': { os: 'android', viewport: {width: 412, height: 869}},
80+
'Galaxy S10': { os: 'android', viewport: {width: 360, height: 760}},
81+
'Galaxy S10 Plus': { os: 'android', viewport: {width: 412, height: 869}},
82+
'Galaxy S10e': { os: 'android', viewport: {width: 412, height: 740}},
83+
'Galaxy S20': { os: 'android', viewport: {width: 360, height: 800}},
84+
'Galaxy S20 FE': { os: 'android', viewport: {width: 412, height: 914}},
85+
'Galaxy S20 Ultra': { os: 'android', viewport: {width: 412, height: 915}},
86+
'Galaxy S20 Plus': { os: 'android', viewport: {width: 384, height: 854}},
87+
'Galaxy S21': { os: 'android', viewport: {width: 360, height: 800}},
88+
'Galaxy S21 FE': { os: 'android', viewport: {width: 360, height: 780}},
89+
'Galaxy S21 Ultra': { os: 'android', viewport: {width: 384, height: 854}},
90+
'Galaxy S21 Plus': { os: 'android', viewport: {width: 360, height: 800}},
91+
'Galaxy S22': { os: 'android', viewport: {width: 360, height: 780}},
92+
'Galaxy S22 Ultra': { os: 'android', viewport: {width: 384, height: 854}},
93+
'Galaxy S23': { os: 'android', viewport: {width: 360, height: 645}},
94+
'Galaxy S23 Plus': { os: 'android', viewport: {width: 360, height: 648}},
95+
'Galaxy S23 Ultra': { os: 'android', viewport: {width: 384, height: 689}},
96+
'Galaxy S24': { os: 'android', viewport: {width: 360, height: 780}},
97+
'Galaxy S24 Plus': { os: 'android', viewport: {width: 384, height: 832}},
98+
'Galaxy S24 Ultra': { os: 'android', viewport: {width: 384, height: 832}},
99+
'Galaxy S7': { os: 'android', viewport: {width: 360, height: 640}},
100+
'Galaxy S7 Edge': { os: 'android', viewport: {width: 360, height: 640}},
101+
'Galaxy S8': { os: 'android', viewport: {width: 360, height: 740}},
102+
'Galaxy S8 Plus': { os: 'android', viewport: {width: 360, height: 740}},
103+
'Galaxy S9': { os: 'android', viewport: {width: 360, height: 740}},
104+
'Galaxy S9 Plus': { os: 'android', viewport: {width: 360, height: 740}},
105+
'Galaxy Tab A7 Lite': { os: 'android', viewport: {width: 534, height: 894}},
106+
'Galaxy Tab A8': { os: 'android', viewport: {width: 800, height: 1280}},
107+
'Galaxy Tab S3': { os: 'android', viewport: {width: 1024, height: 768}},
108+
'Galaxy Tab S4': { os: 'android', viewport: {width: 712, height: 1138}},
109+
'Galaxy Tab S7': { os: 'android', viewport: {width: 800, height: 1192}},
110+
'Galaxy Tab S8': { os: 'android', viewport: {width: 753, height: 1205}},
111+
'Galaxy Tab S8 Plus': { os: 'android', viewport: {width: 825, height: 1318}},
112+
'Huawei Mate 20 Pro': { os: 'android', viewport: {width: 360, height: 780}},
113+
'Huawei P20 Pro': { os: 'android', viewport: {width: 360, height: 747}},
114+
'Huawei P30': { os: 'android', viewport: {width: 360, height: 780}},
115+
'Huawei P30 Pro': { os: 'android', viewport: {width: 360, height: 780}},
116+
'Microsoft Surface Duo': { os: 'android', viewport: {width: 1114, height: 705}},
117+
'Moto G7 Play': { os: 'android', viewport: {width: 360, height: 760}},
118+
'Moto G9 Play': { os: 'android', viewport: {width: 393, height: 786}},
119+
'Moto G Stylus (2022)': { os: 'android', viewport: {width: 432, height: 984}},
120+
'Nexus 5': { os: 'android', viewport: {width: 360, height: 640}},
121+
'Nexus 5X': { os: 'android', viewport: {width: 412, height: 732}},
122+
'Nokia 5': { os: 'android', viewport: {width: 360, height: 640}},
123+
'Nothing Phone (1)': { os: 'android', viewport: {width: 412, height: 915}},
124+
'OnePlus 10 Pro': { os: 'android', viewport: {width: 412, height: 919}},
125+
'OnePlus 11': { os: 'android', viewport: {width: 360, height: 804}},
126+
'OnePlus 6': { os: 'android', viewport: {width: 412, height: 869}},
127+
'OnePlus 6T': { os: 'android', viewport: {width: 412, height: 892}},
128+
'OnePlus 7': { os: 'android', viewport: {width: 412, height: 892}},
129+
'OnePlus 7T': { os: 'android', viewport: {width: 412, height: 914}},
130+
'OnePlus 8': { os: 'android', viewport: {width: 412, height: 915}},
131+
'OnePlus 9': { os: 'android', viewport: {width: 411, height: 915}},
132+
'OnePlus 9 Pro': { os: 'android', viewport: {width: 412, height: 919}},
133+
'OnePlus Nord': { os: 'android', viewport: {width: 412, height: 914}},
134+
'OnePlus Nord 2': { os: 'android', viewport: {width: 412, height: 915}},
135+
'OnePlus Nord CE': { os: 'android', viewport: {width: 412, height: 915}},
136+
'Oppo A12': { os: 'android', viewport: {width: 360, height: 760}},
137+
'Oppo A15': { os: 'android', viewport: {width: 360, height: 800}},
138+
'Oppo A54': { os: 'android', viewport: {width: 360, height: 800}},
139+
'Oppo A5s': { os: 'android', viewport: {width: 360, height: 760}},
140+
'Oppo F17': { os: 'android', viewport: {width: 360, height: 800}},
141+
'Oppo K10': { os: 'android', viewport: {width: 360, height: 804}},
142+
'Pixel 3': { os: 'android', viewport: {width: 412, height: 823}},
143+
'Pixel 3 XL': { os: 'android', viewport: {width: 412, height: 846}},
144+
'Pixel 3a': { os: 'android', viewport: {width: 412, height: 823}},
145+
'Pixel 4': { os: 'android', viewport: {width: 392, height: 830}},
146+
'Pixel 4 XL': { os: 'android', viewport: {width: 412, height: 823}},
147+
'Pixel 4a': { os: 'android', viewport: {width: 393, height: 851}},
148+
'Pixel 5': { os: 'android', viewport: {width: 393, height: 851}},
149+
'Pixel 6': { os: 'android', viewport: {width: 393, height: 786}},
150+
'Pixel 6 Pro': { os: 'android', viewport: {width: 412, height: 892}},
151+
'Pixel 7': { os: 'android', viewport: {width: 412, height: 915}},
152+
'Pixel 7 Pro': { os: 'android', viewport: {width: 412, height: 892}},
153+
'Pixel 8': { os: 'android', viewport: {width: 412, height: 915}},
154+
'Pixel 8 Pro': { os: 'android', viewport: {width: 448, height: 998}},
155+
'Poco M2 Pro': { os: 'android', viewport: {width: 393, height: 873}},
156+
'POCO X3 Pro': { os: 'android', viewport: {width: 393, height: 873}},
157+
'Realme 5i': { os: 'android', viewport: {width: 360, height: 800}},
158+
'Realme 7i': { os: 'android', viewport: {width: 360, height: 800}},
159+
'Realme 8i': { os: 'android', viewport: {width: 360, height: 804}},
160+
'Realme C21Y': { os: 'android', viewport: {width: 360, height: 800}},
161+
'Realme C21': { os: 'android', viewport: {width: 360, height: 800}},
162+
'Realme GT2 Pro': { os: 'android', viewport: {width: 360, height: 804}},
163+
'Redmi 8': { os: 'android', viewport: {width: 360, height: 760}},
164+
'Redmi 9': { os: 'android', viewport: {width: 360, height: 800}},
165+
'Redmi 9C': { os: 'android', viewport: {width: 360, height: 800}},
166+
'Redmi Note 10 Pro': { os: 'android', viewport: {width: 393, height: 873}},
167+
'Redmi Note 8': { os: 'android', viewport: {width: 393, height: 851}},
168+
'Redmi Note 8 Pro': { os: 'android', viewport: {width: 393, height: 851}},
169+
'Redmi Note 9': { os: 'android', viewport: {width: 393, height: 851}},
170+
'Redmi Note 9 Pro Max': { os: 'android', viewport: {width: 393, height: 873}},
171+
'Redmi Y2': { os: 'android', viewport: {width: 360, height: 720}},
172+
'Tecno Spark 7': { os: 'android', viewport: {width: 360, height: 800}},
173+
'Vivo Y22': { os: 'android', viewport: {width: 385, height: 860}},
174+
'Vivo T1': { os: 'android', viewport: {width: 393, height: 873}},
175+
'Vivo V7': { os: 'android', viewport: {width: 360, height: 720}},
176+
'Vivo Y11': { os: 'android', viewport: {width: 360, height: 722}},
177+
'Vivo Y12': { os: 'android', viewport: {width: 360, height: 722}},
178+
'Vivo Y20g': { os: 'android', viewport: {width: 385, height: 854}},
179+
'Vivo Y50': { os: 'android', viewport: {width: 393, height: 786}},
180+
'Xiaomi 12 Pro': { os: 'android', viewport: {width: 412, height: 915}},
181+
'Xperia Z5': { os: 'android', viewport: {width: 360, height: 640}},
182+
'Xperia Z5 Dual': { os: 'android', viewport: {width: 360, height: 640}},
183+
'Zenfone 6': { os: 'android', viewport: {width: 412, height: 892}},
184+
'iPad 10.2 (2019)': { os: 'ios', viewport: {width: 810, height: 1080}},
185+
'iPad 10.2 (2020)': { os: 'ios', viewport: {width: 834, height: 1194}},
186+
'iPad 10.2 (2021)': { os: 'ios', viewport: {width: 810, height: 1080}},
187+
'iPad 9.7 (2017)': { os: 'ios', viewport: {width: 768, height: 1024}},
188+
'iPad Air (2019)': { os: 'ios', viewport: {width: 834, height: 1112}},
189+
'iPad Air (2020)': { os: 'ios', viewport: {width: 820, height: 1180}},
190+
'iPad Air (2022)': { os: 'ios', viewport: {width: 820, height: 1180}},
191+
'iPad mini (2019)': { os: 'ios', viewport: {width: 768, height: 1024}},
192+
'iPad mini (2021)': { os: 'ios', viewport: {width: 744, height: 1133}},
193+
'iPad Pro 11 (2021)': { os: 'ios', viewport: {width: 834, height: 1194}},
194+
'iPad Pro 11 (2022)': { os: 'ios', viewport: {width: 834, height: 1194}},
195+
'iPad Pro 12.9 (2018)': { os: 'ios', viewport: {width: 1024, height: 1366}},
196+
'iPad Pro 12.9 (2020)': { os: 'ios', viewport: {width: 1024, height: 1366}},
197+
'iPad Pro 12.9 (2021)': { os: 'ios', viewport: {width: 1024, height: 1366}},
198+
'iPad Pro 12.9 (2022)': { os: 'ios', viewport: {width: 1024, height: 1366}},
199+
'iPhone 11': { os: 'ios', viewport: {width: 375, height: 812}},
200+
'iPhone 11 Pro': { os: 'ios', viewport: {width: 375, height: 812}},
201+
'iPhone 11 Pro Max': { os: 'ios', viewport: {width: 414, height: 896}},
202+
'iPhone 12': { os: 'ios', viewport: {width: 390, height: 844}},
203+
'iPhone 12 Mini': { os: 'ios', viewport: {width: 375, height: 812}},
204+
'iPhone 12 Pro': { os: 'ios', viewport: {width: 390, height: 844}},
205+
'iPhone 12 Pro Max': { os: 'ios', viewport: {width: 428, height: 926}},
206+
'iPhone 13': { os: 'ios', viewport: {width: 390, height: 844}},
207+
'iPhone 13 Mini': { os: 'ios', viewport: {width: 390, height: 844}},
208+
'iPhone 13 Pro': { os: 'ios', viewport: {width: 390, height: 844}},
209+
'iPhone 13 Pro Max': { os: 'ios', viewport: {width: 428, height: 926}},
210+
'iPhone 14': { os: 'ios', viewport: {width: 390, height: 844}},
211+
'iPhone 14 Plus': { os: 'ios', viewport: {width: 428, height: 926}},
212+
'iPhone 14 Pro': { os: 'ios', viewport: {width: 390, height: 844}},
213+
'iPhone 14 Pro Max': { os: 'ios', viewport: {width: 428, height: 928}},
214+
'iPhone 15': { os: 'ios', viewport: {width: 393, height: 852}},
215+
'iPhone 15 Plus': { os: 'ios', viewport: {width: 430, height: 932}},
216+
'iPhone 15 Pro': { os: 'ios', viewport: {width: 393, height: 852}},
217+
'iPhone 15 Pro Max': { os: 'ios', viewport: {width: 430, height: 932}},
218+
'iPhone 6': { os: 'ios', viewport: {width: 375, height: 667}},
219+
'iPhone 6s': { os: 'ios', viewport: {width: 375, height: 667}},
220+
'iPhone 6s Plus': { os: 'ios', viewport: {width: 414, height: 736}},
221+
'iPhone 7': { os: 'ios', viewport: {width: 375, height: 667}},
222+
'iPhone 7 Plus': { os: 'ios', viewport: {width: 414, height: 736}},
223+
'iPhone 8': { os: 'ios', viewport: {width: 375, height: 667}},
224+
'iPhone 8 Plus': { os: 'ios', viewport: {width: 414, height: 736}},
225+
'iPhone SE (2016)': { os: 'ios', viewport: {width: 320, height: 568}},
226+
'iPhone SE (2020)': { os: 'ios', viewport: {width: 375, height: 667}},
227+
'iPhone SE (2022)': { os: 'ios', viewport: {width: 375, height: 667}},
228+
'iPhone X': { os: 'ios', viewport: {width: 375, height: 812}},
229+
'iPhone XR': { os: 'ios', viewport: {width: 414, height: 896}},
230+
'iPhone XS': { os: 'ios', viewport: {width: 375, height: 812}},
231+
'iPhone XS Max': { os: 'ios', viewport: {width: 414, height: 896}},
232+
}
233+
}

src/lib/ctx.ts

+31-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Context, Env, Config } from '../types.js'
2-
import { DEFAULT_CONFIG } from './config.js'
1+
import { Context, Env, WebConfig, MobileConfig } from '../types.js'
2+
import constants from './constants.js'
33
import { version } from '../../package.json'
44
import { validateConfig } from './schemaValidation.js'
55
import logger from './logger.js'
@@ -9,37 +9,53 @@ import fs from 'fs'
99

1010
export default (options: Record<string, string>): Context => {
1111
let env: Env = getEnv();
12-
let viewports: Array<{width: number, height: number}> = []
13-
let config: Config = DEFAULT_CONFIG;
12+
let webConfig: WebConfig;
13+
let mobileConfig: MobileConfig;
14+
let config = constants.DEFAULT_CONFIG;
1415

1516
try {
1617
if (options.config) {
1718
config = JSON.parse(fs.readFileSync(options.config, 'utf-8'));
19+
1820
// resolutions supported for backward compatibility
19-
if (config.web.resolutions) {
21+
if (config.web?.resolutions) {
2022
config.web.viewports = config.web.resolutions;
2123
delete config.web.resolutions;
2224
}
25+
26+
// validate config
27+
if (!validateConfig(config)) {
28+
throw new Error(validateConfig.errors[0].message);
29+
}
2330
}
24-
25-
// validate config
26-
if (!validateConfig(config)) throw new Error(validateConfig.errors[0].message);
2731
} catch (error: any) {
2832
console.log(`[smartui] Error: ${error.message}`);
2933
process.exit();
3034
}
3135

32-
for (let viewport of config.web.viewports) viewports.push({ width: viewport[0], height: viewport[1] || 0});
36+
if (config.web) {
37+
webConfig = {browsers: config.web.browsers, viewports: []};
38+
for (let viewport of config.web?.viewports) webConfig.viewports.push({ width: viewport[0], height: viewport[1] || 0});
39+
}
40+
if (config.mobile) {
41+
mobileConfig = {
42+
devices: config.mobile.devices,
43+
fullPage: config.mobile.fullPage || true,
44+
orientation: config.mobile.orientation || constants.MOBILE_ORIENTATION_PORTRAIT,
45+
}
46+
}
47+
3348
return {
3449
env: env,
3550
log: logger,
3651
client: new httpClient(env),
37-
webConfig: {
38-
browsers: config.web.browsers,
39-
viewports: viewports,
40-
waitForPageRender: config.web.waitForPageRender || 0,
41-
waitForTimeout: config.web.waitForTimeout || 0,
42-
enableJavaScript: config.web.enableJavaScript || false
52+
config: {
53+
web: webConfig,
54+
mobile: mobileConfig,
55+
waitForPageRender: config.waitForPageRender || 0,
56+
waitForTimeout: config.waitForTimeout || 0,
57+
enableJavaScript: config.enableJavaScript || false,
58+
allowedHostnames: config.allowedHostnames || []
4359
},
4460
webStaticConfig: [],
4561
git: {

src/lib/env.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ export default (): Env => {
55
PROJECT_TOKEN = '',
66
SMARTUI_CLIENT_API_URL = 'https://api.lambdatest.com/visualui/1.0',
77
LT_SDK_LOG_LEVEL,
8-
LT_SDK_DEBUG
8+
LT_SDK_DEBUG,
9+
GITHUB_ACTIONS
910
} = process.env
1011

1112
return {
1213
PROJECT_TOKEN,
1314
SMARTUI_CLIENT_API_URL,
1415
LT_SDK_LOG_LEVEL,
15-
LT_SDK_DEBUG
16+
LT_SDK_DEBUG,
17+
GITHUB_ACTIONS
1618
}
1719
}

0 commit comments

Comments
 (0)