Skip to content

Commit 526b65b

Browse files
fix: run ios simulator tests on default port (#51)
* fix: run ios simulator tests on default port * fix linting
1 parent 350e52c commit 526b65b

File tree

9 files changed

+181
-168
lines changed

9 files changed

+181
-168
lines changed

.prettierignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.github/
2+
README.md
3+
docs/commands.md
4+
finder.ts
5+
flutter-by/wdio-flutter-by-service/package.json
6+
flutter-by/wdio-flutter-by-service/package-lock.json
7+
*.conf.ts
8+
CHANGELOG.md

.prettierrc

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"singleQuote": true,
3-
"tabWidth": 3,
4-
"semi": true,
5-
"trailingComma": "all",
6-
"useTabs": false
2+
"singleQuote": true,
3+
"tabWidth": 3,
4+
"semi": true,
5+
"trailingComma": "all",
6+
"useTabs": false
77
}

android.conf.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import { join } from 'node:path';
22
import { config as baseConfig } from './wdio.conf.ts';
33

44
export const config: WebdriverIO.Config = {
5-
...baseConfig,
6-
capabilities: [
7-
{
8-
// capabilities for local Appium web tests on an Android Emulator
9-
platformName: 'Android',
10-
'appium:automationName': 'FlutterIntegration',
11-
'appium:orientation': 'PORTRAIT',
12-
'appium:app':
13-
process.env.APP_PATH || join(process.cwd(), 'app-debug.apk'),
14-
'appium:newCommandTimeout': 240,
15-
'appium:flutterServerLaunchTimeout': 10000,
16-
},
17-
],
5+
...baseConfig,
6+
capabilities: [
7+
{
8+
// capabilities for local Appium web tests on an Android Emulator
9+
platformName: 'Android',
10+
'appium:automationName': 'FlutterIntegration',
11+
'appium:orientation': 'PORTRAIT',
12+
'appium:app':
13+
process.env.APP_PATH || join(process.cwd(), 'app-debug.apk'),
14+
'appium:newCommandTimeout': 240,
15+
'appium:flutterServerLaunchTimeout': 10000,
16+
},
17+
],
1818
};

finder.ts

+113-113
Original file line numberDiff line numberDiff line change
@@ -3,122 +3,122 @@ import { command } from 'webdriver';
33
import path from 'path';
44

55
export async function registerCommands() {
6-
const utils = await import(
7-
path.join(
8-
require.resolve('webdriverio').replace('cjs/index.js', ''),
9-
'utils',
10-
'getElementObject.js',
11-
)
12-
);
6+
const utils = await import(
7+
path.join(
8+
require.resolve('webdriverio').replace('cjs/index.js', ''),
9+
'utils',
10+
'getElementObject.js',
11+
)
12+
);
1313

14-
function handler(multi: boolean = false) {
15-
return async function (value: string) {
16-
let findElement;
14+
function handler(multi: boolean = false) {
15+
return async function (value: string) {
16+
let findElement;
1717

18-
let args = ['key', value];
19-
let suffix = multi ? 'elements' : 'element';
20-
if (this['elementId']) {
21-
args = [this['elementId'], 'key', value];
22-
findElement = command(
23-
'POST',
24-
`/session/:sessionId/element/:elementId/${suffix}`,
25-
{
26-
command: 'flutterFinderByKey',
27-
description: 'a new WebDriver command',
28-
ref: 'https://vendor.com/commands/#myNewCommand',
29-
variables: [
30-
{
31-
name: 'elementId',
32-
type: 'string',
33-
description: 'a valid parameter',
34-
required: true,
35-
},
36-
],
37-
parameters: [
38-
{
39-
name: 'using',
40-
type: 'string',
41-
description: 'a valid parameter',
42-
required: true,
43-
},
44-
{
45-
name: 'value',
46-
type: 'string',
47-
description: 'a valid parameter',
48-
required: true,
49-
},
50-
],
51-
returns: {
52-
type: 'object',
53-
name: 'element',
54-
description:
55-
"A JSON representation of an element object, e.g. `{ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT_1' }`.",
56-
},
57-
},
58-
);
59-
} else {
60-
findElement = command('POST', `/session/:sessionId/${suffix}`, {
61-
command: 'flutterFinderByKey',
62-
description: 'a new WebDriver command',
63-
ref: 'https://vendor.com/commands/#myNewCommand',
64-
variables: [],
65-
parameters: [
66-
{
67-
name: 'using',
68-
type: 'string',
69-
description: 'a valid parameter',
70-
required: true,
71-
},
72-
{
73-
name: 'value',
74-
type: 'string',
75-
description: 'a valid parameter',
76-
required: true,
77-
},
78-
{
79-
name: 'context',
80-
type: 'string',
81-
description: 'a valid parameter',
82-
required: false,
83-
},
84-
],
85-
returns: {
86-
type: 'object',
87-
name: 'element',
88-
description:
89-
"A JSON representation of an element object, e.g. `{ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT_1' }`.",
90-
},
91-
});
92-
}
18+
let args = ['key', value];
19+
let suffix = multi ? 'elements' : 'element';
20+
if (this['elementId']) {
21+
args = [this['elementId'], 'key', value];
22+
findElement = command(
23+
'POST',
24+
`/session/:sessionId/element/:elementId/${suffix}`,
25+
{
26+
command: 'flutterFinderByKey',
27+
description: 'a new WebDriver command',
28+
ref: 'https://vendor.com/commands/#myNewCommand',
29+
variables: [
30+
{
31+
name: 'elementId',
32+
type: 'string',
33+
description: 'a valid parameter',
34+
required: true,
35+
},
36+
],
37+
parameters: [
38+
{
39+
name: 'using',
40+
type: 'string',
41+
description: 'a valid parameter',
42+
required: true,
43+
},
44+
{
45+
name: 'value',
46+
type: 'string',
47+
description: 'a valid parameter',
48+
required: true,
49+
},
50+
],
51+
returns: {
52+
type: 'object',
53+
name: 'element',
54+
description:
55+
"A JSON representation of an element object, e.g. `{ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT_1' }`.",
56+
},
57+
},
58+
);
59+
} else {
60+
findElement = command('POST', `/session/:sessionId/${suffix}`, {
61+
command: 'flutterFinderByKey',
62+
description: 'a new WebDriver command',
63+
ref: 'https://vendor.com/commands/#myNewCommand',
64+
variables: [],
65+
parameters: [
66+
{
67+
name: 'using',
68+
type: 'string',
69+
description: 'a valid parameter',
70+
required: true,
71+
},
72+
{
73+
name: 'value',
74+
type: 'string',
75+
description: 'a valid parameter',
76+
required: true,
77+
},
78+
{
79+
name: 'context',
80+
type: 'string',
81+
description: 'a valid parameter',
82+
required: false,
83+
},
84+
],
85+
returns: {
86+
type: 'object',
87+
name: 'element',
88+
description:
89+
"A JSON representation of an element object, e.g. `{ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT_1' }`.",
90+
},
91+
});
92+
}
9393

94-
const response = await findElement.call(browser, ...args);
95-
console.log(utils.getElement);
96-
try {
97-
if (multi) {
98-
return response.map((element: any) =>
99-
utils.getElement.call(this, null, element),
100-
);
101-
} else {
102-
return utils.getElement.call(this, null, response);
103-
}
104-
} catch (e) {
105-
console.log(e);
106-
}
107-
};
108-
}
109-
browser.addCommand('flutterFinderByKey$', handler());
110-
browser.addCommand('flutterFinderByKey$', handler(), true);
94+
const response = await findElement.call(browser, ...args);
95+
console.log(utils.getElement);
96+
try {
97+
if (multi) {
98+
return response.map((element: any) =>
99+
utils.getElement.call(this, null, element),
100+
);
101+
} else {
102+
return utils.getElement.call(this, null, response);
103+
}
104+
} catch (e) {
105+
console.log(e);
106+
}
107+
};
108+
}
109+
browser.addCommand('flutterFinderByKey$', handler());
110+
browser.addCommand('flutterFinderByKey$', handler(), true);
111111

112-
browser.addCommand('flutterFinderByKey$$', handler(true));
113-
browser.addCommand('flutterFinderByKey$$', handler(true), true);
112+
browser.addCommand('flutterFinderByKey$$', handler(true));
113+
browser.addCommand('flutterFinderByKey$$', handler(true), true);
114114

115-
/**
116-
*
117-
* 1. Element visible
118-
* 2. Element not visible
119-
* 3. element enable/disabled
120-
* 4. Element count
121-
* 6.
122-
*
123-
*/
115+
/**
116+
*
117+
* 1. Element visible
118+
* 2. Element not visible
119+
* 3. element enable/disabled
120+
* 4. Element count
121+
* 6.
122+
*
123+
*/
124124
}

ios.conf.ts

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export const config: WebdriverIO.Config = {
1414
'appium:newCommandTimeout': 240,
1515
'appium:usePreinstalledWDA': true,
1616
'appium:showIOSLog': true,
17-
'appium:flutterSystemPort': 31321,
1817
'appium:wdaLocalPort': 8456,
1918
'appium:flutterServerLaunchTimeout': 25000,
2019
},

src/driver.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ export class AppiumFlutterDriver extends BaseDriver<FlutterDriverConstraints> {
212212
}
213213

214214
const systemPort =
215-
this.internalCaps.flutterSystemPort ?? (await getFreePort());
215+
this.internalCaps.flutterSystemPort ||
216+
(isIosSimulator ? null : await getFreePort());
216217
const udid = this.proxydriver.opts.udid!;
217218

218219
this.flutterPort = await fetchFlutterServerPort.bind(this)({
@@ -352,13 +353,10 @@ export class AppiumFlutterDriver extends BaseDriver<FlutterDriverConstraints> {
352353
);
353354

354355
// Add port parameter to launch argument and only supported for iOS
355-
if (
356-
this.proxydriver instanceof XCUITestDriver &&
357-
this.internalCaps?.flutterSystemPort
358-
) {
356+
if (this.proxydriver instanceof XCUITestDriver) {
359357
launchArgs.arguments = _.flatten([
360358
launchArgs.arguments,
361-
`--flutter-server-port=${this.internalCaps.flutterSystemPort}`,
359+
`--flutter-server-port=${this.internalCaps?.flutterSystemPort || this.flutterPort}`,
362360
]);
363361
this.log.info(
364362
'Attaching launch arguments to XCUITestDriver ' +

src/utils.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,19 @@ export async function fetchFlutterServerPort(
124124
let devicePort = startPort;
125125
let forwardedPort = systemPort;
126126

127-
if (isIosSimulator && systemPort) {
127+
if (isIosSimulator && (systemPort || devicePort)) {
128128
try {
129129
this.log.info(
130-
`Checking if flutter server is running on port ${systemPort} for simulator with id ${udid}`,
130+
`Checking if flutter server is running on port ${systemPort || devicePort} for simulator with id ${udid}`,
131+
);
132+
await waitForFlutterServer.bind(this)(
133+
(systemPort || devicePort)!,
134+
packageName,
131135
);
132-
await waitForFlutterServer.bind(this)(systemPort!, packageName);
133136
this.log.info(
134-
`Flutter server is successfully running on port ${systemPort}`,
137+
`Flutter server is successfully running on port ${systemPort || devicePort}`,
135138
);
136-
return systemPort!;
139+
return (systemPort || devicePort)!;
137140
} catch (e) {
138141
return null;
139142
}

test/specs/test.e2e.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ async function performLogin(userName = 'admin', password = '1234') {
99

1010
await browser.flutterByValueKey$('password_text_field').clearValue();
1111
await browser.flutterByValueKey$('password').addValue(password);
12-
expect(await browser.flutterByType$('ElevatedButton').flutterByType$("Text").getText()).toEqual('Login');
12+
expect(
13+
await browser
14+
.flutterByType$('ElevatedButton')
15+
.flutterByType$('Text')
16+
.getText(),
17+
).toEqual('Login');
1318
await browser.flutterByType$('ElevatedButton').click();
1419
}
1520

@@ -30,7 +35,7 @@ describe('My Login application', () => {
3035
}
3136
await browser.installApp(process.env.APP_PATH);
3237
await browser.pause(2000);
33-
if (await browser.isAppInstalled(appID)){
38+
if (await browser.isAppInstalled(appID)) {
3439
console.log('App is installed');
3540
await browser.execute('flutter: launchApp', {
3641
appId: appID,

0 commit comments

Comments
 (0)