Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions driver/lib/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,19 @@ class FlutterDriver extends BaseDriver<FluttertDriverConstraints> {
public async executeCommand(cmd: string, ...args: [string, [{skipAttachObservatoryUrl: string; any: any}]]) {
if (new RegExp(/^[\s]*mobile:[\s]*(activateApp|launchApp)$/).test(args[0])) {
const {skipAttachObservatoryUrl = false} = args[1][0];
await this.proxydriver?.executeCommand(cmd, ...args);
if (skipAttachObservatoryUrl) {
// This bypasses BaseDriver.executeCommand, so pause the FlutterDriver CommandTimeout here:
// the reconnect can wait for the observatory URL much longer than newCommandTimeout.
await this.clearNewCommandTimeout();
try {
await this.proxydriver?.executeCommand(cmd, ...args);
if (skipAttachObservatoryUrl) {
return;
}
await reConnectFlutterDriver.bind(this)(this.internalCaps);
return;
} finally {
await this.startNewCommandTimeout();
}
await reConnectFlutterDriver.bind(this)(this.internalCaps);
return;
} else if (new RegExp(/^[\s]*mobile:[\s]*terminateApp$/).test(args[0])) {
// to make the behavior as same as this.terminateApp
return await this.proxydriver?.executeCommand(cmd, ...args);
Expand Down
55 changes: 40 additions & 15 deletions driver/test/mobile-launch-app.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,59 @@ import {FlutterDriver} from '../build/lib/driver.js';

const noopLog = {info() {}, debug() {}, warn() {}, error() {}, errorWithException() {}};

// Records the order of proxy calls and newCommandTimeout changes.
function fakeDriver() {
const events = [];
return {
events,
log: noopLog,
currentContext: 'FLUTTER',
internalCaps: {platformName: 'iOS'},
proxydriver: {executeCommand: mock.fn(async () => events.push('proxy'))},
clearNewCommandTimeout: async () => events.push('clearTimeout'),
startNewCommandTimeout: async () => events.push('startTimeout'),
};
}

// The reconnect that follows the launch fails right away here because no device-log monitor
// was started, which shows that the driver tried to re-attach to the Dart VM.
it('forwards mobile: launchApp to XCUITest from the FLUTTER context and reconnects', async () => {
const proxydriver = {executeCommand: mock.fn(async () => {})};
const driver = fakeDriver();
const params = {bundleId: 'com.example.app', arguments: ['--vm-service-port=9123']};

await assert.rejects(
FlutterDriver.prototype.executeCommand.call(
{log: noopLog, currentContext: 'FLUTTER', internalCaps: {platformName: 'iOS'}, proxydriver},
'execute',
'mobile: launchApp',
[params],
),
FlutterDriver.prototype.executeCommand.call(driver, 'execute', 'mobile: launchApp', [params]),
/mandatory syslog service/,
);

assert.deepEqual(proxydriver.executeCommand.mock.calls[0].arguments, ['execute', 'mobile: launchApp', [params]]);
assert.deepEqual(driver.proxydriver.executeCommand.mock.calls[0].arguments, [
'execute',
'mobile: launchApp',
[params],
]);
});

it('skips the reconnect for mobile: launchApp when skipAttachObservatoryUrl is set', async () => {
const proxydriver = {executeCommand: mock.fn(async () => {})};
const driver = fakeDriver();

await FlutterDriver.prototype.executeCommand.call(
{log: noopLog, currentContext: 'FLUTTER', internalCaps: {platformName: 'iOS'}, proxydriver},
'execute',
'mobile: launchApp',
[{bundleId: 'com.example.app', skipAttachObservatoryUrl: true}],
await FlutterDriver.prototype.executeCommand.call(driver, 'execute', 'mobile: launchApp', [
{bundleId: 'com.example.app', skipAttachObservatoryUrl: true},
]);

assert.equal(driver.proxydriver.executeCommand.mock.callCount(), 1);
});

// The reconnect can wait for the observatory URL far longer than newCommandTimeout, so the
// timeout must be paused for the whole command and restarted even when the reconnect fails.
it('pauses newCommandTimeout while launching and reconnecting', async () => {
const driver = fakeDriver();

await assert.rejects(
FlutterDriver.prototype.executeCommand.call(driver, 'execute', 'mobile: activateApp', [
{bundleId: 'com.example.app'},
]),
/mandatory syslog service/,
);

assert.equal(proxydriver.executeCommand.mock.callCount(), 1);
assert.deepEqual(driver.events, ['clearTimeout', 'proxy', 'startTimeout']);
});
Loading