Skip to content

Commit ca9c0ba

Browse files
authored
chore: adjust implementation of #797 (#799)
* chore: adjust * fix the arg * tweak more * revert unexpected change * revert some * back works in native always * add missing @ * fix reference * update the call * remove commands which did not work * add example * revert a bit
1 parent 7b8dd80 commit ca9c0ba

File tree

8 files changed

+40
-490
lines changed

8 files changed

+40
-490
lines changed

README.md

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -311,19 +311,13 @@ Please replace them properly with your client.
311311

312312
This module extends the `appium-flutter-driver` with custom visibility-related commands using `driver.execute()`.
313313

314-
## ✅ Supported Commands
314+
## ✅ Supported Shortcut Commands
315+
315316
| **Command** | **Status** | **Example Usage** | **Target** |
316317
|---------------------|------------|--------------------------------------------------------------------------------------------------------------------------|------------|
317318
| `assertVisible` || `driver.execute('flutter:assertVisible', { key: 'myKey' })`<br>`driver.execute('flutter:assertVisible', { text: 'Login' })` | Widget |
318319
| `assertNotVisible` || `driver.execute('flutter:assertNotVisible', { key: 'hiddenWidget' })` | Widget |
319320
| `assertTappable` || `driver.execute('flutter:assertTappable', { label: 'Submit' })` | Widget |
320-
| `tap` || `driver.execute('flutter:tap', [{ key: 'submit_button' }])` | Widget |
321-
| `click` || `driver.execute('flutter:click', { text: 'Continue' })` | Widget |
322-
`getText` | ✅ | `driver.execute('flutter:getText', { key: 'counterText' })` | Widget |
323-
| `pageBack` || `await driver.execute('flutter:pageBack')` | Navigation |
324-
| `clear` || `await driver.execute('flutter:clear', { key: 'emailInput' })` | Input Field |
325-
326-
327321

328322
## 🔍 Input Formats
329323

@@ -343,7 +337,22 @@ These map to Flutter finders:
343337
These commands are typically invoked using a client helper method like:
344338

345339
```ts
340+
// TypeScript
346341
await assertVisible(driver, { key: 'submit_button' });
342+
```
343+
344+
Or as a flutter command.
345+
346+
```ruby
347+
# ruby
348+
driver.execute_script 'flutter:assertVisible', {text: 'Tap me!'}, 10000
349+
350+
# This is equivalent to
351+
text_finder = by_text 'Tap me!'
352+
driver.execute_script 'flutter:assertVisible', text_finder, 10000
353+
# or
354+
driver.execute_script 'flutter:waitFor', text_finder, 10000
355+
```
347356

348357
**NOTE**
349358
>`flutter:launchApp` launches an app via instrument service. `mobile:activateApp` and `driver.activate_app` are via XCTest API. They are a bit different.
@@ -393,13 +402,13 @@ This is a command extension for Flutter Driver, utilizing the [CommandExtension-
393402
Available commands:
394403

395404
- `dragAndDropWithCommandExtension` – performs a drag-and-drop action on the screen by specifying the start and end coordinates and the action duration.
396-
- `getTextWithCommandExtension` - get text data from Text widget that contains TextSpan widgets.
405+
- `getTextWithCommandExtension` - get text data from Text widget that contains TextSpan widgets.
397406

398407
### How to use
399408

400409
Copy the sample dart files to the `lib` folder of your project. Please note that you don't need to copy all files, just copy the file matched with the command you need.
401410
- dragAndDropWithCommandExtension: [drag_commands.dart](./example/dart/drag_commands.dart)
402-
- getTextWithCommandExtension: [get_text_command.dart](./example/dart/get_text_command.dart)
411+
- getTextWithCommandExtension: [get_text_command.dart](./example/dart/get_text_command.dart)
403412

404413
The entry point must include the `List<CommandExtension>?` commands argument in either `main.dart` or `test_main.dart` to properly handle the command extension.
405414

driver/README.md

Lines changed: 1 addition & 429 deletions
Large diffs are not rendered by default.

driver/lib/commands/assertions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ function getFinderBase64(input: FinderInput): string {
3636
}
3737

3838
if ('key' in input) {
39-
return serializeFinder(byValueKey(input.key));
39+
return byValueKey(input.key);
4040
}
4141

4242
if ('text' in input) {
43-
return serializeFinder(byText(input.text));
43+
return byText(input.text);
4444
}
4545

4646
if ('label' in input) {
47-
return serializeFinder(byTooltip(input.label));
47+
return byTooltip(input.label);
4848
}
4949

5050
throw new Error('Invalid finder input: must provide key, text, label, raw finder, or FlutterElement');

driver/lib/commands/execute.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ import {
66
scroll,
77
scrollIntoView,
88
scrollUntilVisible,
9-
scrollUntilTapable,
10-
pageBack
9+
scrollUntilTapable
1110
} from './execute/scroll';
1211
import {
1312
waitFor,
1413
waitForAbsent,
1514
waitForTappable
1615
} from './execute/wait';
17-
import { clear, getText } from './element';
18-
import { tap, click } from './gesture';
1916
import {
2017
assertVisible,
2118
assertNotVisible,
@@ -135,7 +132,7 @@ const commandHandlers: CommandMap = {
135132
await driver.socket!.executeSocketCommand({ command: 'enter_text', text }),
136133
requestData: async (driver, message: string) =>
137134
await driver.socket!.executeSocketCommand({ command: 'request_data', message }),
138-
longTap: async (driver, finder: string, durationOrOptions?: LongTapOptions) =>
135+
longTap: async (driver, finder: string, durationOrOptions: LongTapOptions) =>
139136
await longTap(driver, finder, durationOrOptions),
140137
waitForFirstFrame: async (driver) =>
141138
await driver.executeElementCommand('waitForCondition', '', { conditionName: 'FirstFrameRasterizedCondition' }),
@@ -156,25 +153,10 @@ const commandHandlers: CommandMap = {
156153
}),
157154
assertVisible: async (driver, input: FinderInput, timeout = 5000) =>
158155
await assertVisible(driver, input, timeout),
159-
160156
assertNotVisible: async (driver, input: FinderInput, timeout = 5000) =>
161157
await assertNotVisible(driver, input, timeout),
162-
163158
assertTappable: async (driver, input: FinderInput, timeout = 5000) =>
164159
await assertTappable(driver, input, timeout),
165-
166-
tap: async (driver, gestures: Record<string, any>[], longPress: boolean = false) =>
167-
await tap.call(driver, gestures, longPress),
168-
169-
click: async (driver, input: FinderInput) =>
170-
await click.call(driver, input),
171-
getText: async (driver, element: string) =>
172-
await getText.call(driver, element),
173-
pageBack: async (driver) =>
174-
await pageBack.call(driver),
175-
clear: async (driver, input: FinderInput) =>
176-
await clear.call(driver, input),
177-
178160
getTextWithCommandExtension: async (driver, params: { findBy: string }) =>
179161
await driver.socket!.executeSocketCommand({
180162
command: 'getTextWithCommandExtension',

driver/lib/commands/execute/scroll.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,12 @@ export const scroll = async (
4343
export const longTap = async (
4444
self: FlutterDriver,
4545
elementBase64: string,
46-
durationOrOptions: number | {
46+
options: {
4747
durationMilliseconds: number;
4848
frequency?: number;
49-
} = 1000, // Default to 1000ms if nothing provided
49+
},
5050
) => {
51-
const options = typeof durationOrOptions === 'number'
52-
? { durationMilliseconds: durationOrOptions }
53-
: durationOrOptions;
54-
55-
const { durationMilliseconds, frequency = 60 } = options;
51+
const { durationMilliseconds = 1000, frequency = 60 } = options;
5652

5753
if (typeof durationMilliseconds !== 'number' || typeof frequency !== 'number') {
5854
throw new Error(`Invalid longTap options: ${JSON.stringify(options)}`);
@@ -204,13 +200,3 @@ export const scrollIntoView = async (
204200

205201
return await self.executeElementCommand(`scrollIntoView`, elementBase64, args);
206202
};
207-
208-
209-
export const pageBack = async function (this: FlutterDriver): Promise<void> {
210-
if (this.proxydriver && typeof this.proxydriver.back === 'function') {
211-
return await this.proxydriver.back(); // use platform driver
212-
}
213-
214-
// fallback
215-
throw new Error(`Back navigation is not supported on this platform.`);
216-
};

driver/lib/driver.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ class FlutterDriver extends BaseDriver<FluttertDriverConstraints> {
162162
return await this.proxydriver.terminateApp(appId);
163163
}
164164

165+
public async back() {
166+
return await this.proxydriver.back();
167+
}
168+
165169
public async getOrientation(): Promise<string> {
166170
switch (_.toLower(this.internalCaps.platformName)) {
167171
case PLATFORM.IOS:
@@ -217,7 +221,7 @@ class FlutterDriver extends BaseDriver<FluttertDriverConstraints> {
217221
} else if (cmd === `receiveAsyncResponse`) {
218222
logger.debug(`Executing FlutterDriver response '${cmd}'`);
219223
return await this.receiveAsyncResponse(...args);
220-
} else if ([`setOrientation`, `getOrientation`].includes(cmd)) {
224+
} else if ([`setOrientation`, `getOrientation`, `back`].includes(cmd)) {
221225
// The `setOrientation` and `getOrientation` commands are handled differently
222226
// for iOS and Android platforms. These commands are deferred to the base driver's
223227
// implementation (`super.executeCommand`) to ensure compatibility with both platforms

example/ruby/example_sample2.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,16 @@ def test_run_example_android
4747
@driver.context = 'FLUTTER'
4848

4949
text_finder = by_text 'Tap me!'
50+
51+
@driver.execute_script 'flutter:assertVisible', {text: 'Tap me!'}, 10000
52+
5053
element = ::Appium::Flutter::Element.new(@driver, finder: text_finder)
51-
# @driver.execute_script('flutter:waitForTappable', text_finder, 1000)
54+
# @driver.execute_script('flutter:waitForTappable', text_finder, 10000)
5255

5356
assert_equal 'Tap me!', element.text
5457

5558
element.click
56-
element.click
59+
@driver.execute_script 'flutter:clickElement', text_finder, {timeout:10000}
5760

5861
text_finder = by_text 'Taps: 2'
5962
element = ::Appium::Flutter::Element.new(@driver, finder: text_finder)
@@ -75,5 +78,7 @@ def test_run_example_android
7578
text_finder = by_text 'Tap me!'
7679
element = ::Appium::Flutter::Element.new(@driver, finder: text_finder)
7780
assert_equal 'Tap me!', element.text
81+
82+
@driver.back
7883
end
7984
end

package.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)