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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ These Appium commands can work across context
- `getContexts`
- `activateApp('appId')`/`mobile:activateApp`
- `mobile:activateApp` has `skipAttachObservatoryUrl` key to not try to attach to an observatory url. e.g. `driver.execute_script 'mobile:activateApp', {skipAttachObservatoryUrl: true, appId: 'com.android.chrome'}`
- `mobile:launchApp` (iOS)
- Relaunches the app with `arguments`/`environment` via XCUITest, then attaches to the observatory url (`skipAttachObservatoryUrl` is honored as well). Use it instead of `activateApp` when the app needs launch arguments again, e.g. with `appium:dartVmServicePort`: `driver.execute_script 'mobile:launchApp', {bundleId: 'com.example.bundleId', arguments: ['--vm-service-port=8283', '--disable-service-auth-codes']}`
- `terminateApp('appId')`/`mobile:terminateApp`
- `installApp(appPath, options)`
- `getClipboard`
Expand Down
2 changes: 1 addition & 1 deletion driver/lib/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class FlutterDriver extends BaseDriver<FluttertDriverConstraints> {
}

public async executeCommand(cmd: string, ...args: [string, [{skipAttachObservatoryUrl: string; any: any}]]) {
if (new RegExp(/^[\s]*mobile:[\s]*activateApp$/).test(args[0])) {
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) {
Expand Down
38 changes: 38 additions & 0 deletions driver/test/mobile-launch-app.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import assert from 'node:assert/strict';
import {it, mock} from 'node:test';

import {FlutterDriver} from '../build/lib/driver.js';

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

// 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 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],
),
/mandatory syslog service/,
);

assert.deepEqual(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 () => {})};

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

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