diff --git a/README.md b/README.md index febf7ed9..70d8d6a5 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,8 @@ Legend: | [checkHealth](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/checkHealth.html) | :ok: | `driver.execute('flutter:checkHealth')` | Session | | [clearTimeline](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/clearTimeline.html) | :ok: | `driver.execute('flutter:clearTimeline')` | Session | | [close](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/close.html) | :ok: | [`driver.deleteSession()`](https://github.com/truongsinh/appium-flutter-driver/blob/5df7386b59bb99008cb4cff262552c7259bb2af2/example/src/index.js#L55) | Session | -| [enterText](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/enterText.html) | :x: | `driver.execute('flutter:enterText', 'I can enter text')` | Session | +| [enterText](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/enterText.html) | :x: | `driver.elementSendKeys(find.byType('TextField'), 'I can enter text')` (no focus required)\ +`driver.elementClick(find.byType('TextField')); driver.execute('flutter:enterText', 'I can enter text')` (focus required by tap/click first) | Session | | [forceGC](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/forceGC.html) | :ok: | `driver.execute('flutter:forceGC')` | Session | | [getBottomLeft](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getBottomLeft.html) | :ok: | `driver.execute('flutter:getBottomLeft', buttonFinder)` | Widget | | [getBottomRight](https://api.flutter.dev/flutter/flutter_driver/FlutterDriver/getBottomRight.html) | :ok: | `driver.execute('flutter:getBottomRight', buttonFinder)` | Widget | diff --git a/driver/lib/commands/element.ts b/driver/lib/commands/element.ts index 385410c1..ff6a4bf5 100755 --- a/driver/lib/commands/element.ts +++ b/driver/lib/commands/element.ts @@ -4,3 +4,17 @@ export const getText = async function(this: FlutterDriver, el: string) { const response = await this.executeElementCommand(`get_text`, el); return response.text; }; + +export const setValue = async function(this: FlutterDriver, textInput: string | [string], el: string) { + const clickPromise = this.click(el); // acquire focus + let text = ``; + if (textInput instanceof Array) { + text = textInput.reduce((previousValue, currentValue) => `${previousValue}${currentValue}`); + } else if (typeof textInput === `string`) { + text = textInput; + } else { + throw new Error(`Invalid textInput: ${textInput}`); + } + await clickPromise; + await this.execute(`flutter:enterText`, [text]); +}; diff --git a/driver/lib/driver.ts b/driver/lib/driver.ts index eac0c8e2..c50b6a4a 100755 --- a/driver/lib/driver.ts +++ b/driver/lib/driver.ts @@ -9,7 +9,7 @@ import { createSession, deleteSession } from './sessions/session'; import { driverShouldDoProxyCmd, FLUTTER_CONTEXT_NAME, getContexts, getCurrentContext, setContext } from './commands/context'; -import { getText } from './commands/element'; +import { getText, setValue } from './commands/element'; import { execute } from './commands/execute'; import { click, performTouch, tap, tapEl } from './commands/gesture'; import { getScreenshot } from './commands/screen'; @@ -35,6 +35,7 @@ class FlutterDriver extends BaseDriver { // element public getText = getText; + public setValue = setValue; public getScreenshot = getScreenshot; // gesture diff --git a/driver/package.json b/driver/package.json index bff490b7..1e6a0240 100644 --- a/driver/package.json +++ b/driver/package.json @@ -5,7 +5,7 @@ "appium", "flutter" ], - "version": "0.0.17", + "version": "0.0.18", "author": "TruongSinh Tran-Nguyen ", "license": "MIT", "repository": { diff --git a/example/flutter_app_under_test/test_driver/main_test.dart b/example/flutter_app_under_test/test_driver/main_test.dart index fc70d1ea..dbe1ddc9 100644 --- a/example/flutter_app_under_test/test_driver/main_test.dart +++ b/example/flutter_app_under_test/test_driver/main_test.dart @@ -59,7 +59,7 @@ void main() { await driver.waitForAbsent(find.byTooltip('counter_tooltip')); expect(await driver.getText(find.text('This is 2nd route')), 'This is 2nd route'); - await driver.scrollUntilVisible(find.byType('ListView'), find.byType('TextField'), dxScroll: 90, dyScroll: -40); + await driver.scrollUntilVisible(find.byType('ListView'), find.byType('TextField'), dxScroll: 90, dyScroll: -400); await driver.scroll(find.byType('ListView'), 50, 100, Duration(milliseconds: 200), frequency: 30); await driver.scrollIntoView(find.byType('ListView'), alignment: 1.4); await driver.tap(find.byType('TextField')); diff --git a/example/nodejs/src/index.js b/example/nodejs/src/index.js index 4cc60df5..df70aeec 100644 --- a/example/nodejs/src/index.js +++ b/example/nodejs/src/index.js @@ -114,8 +114,7 @@ const opts = { await driver.execute('flutter:scrollUntilVisible', find.byType('ListView'), {item:find.byType('TextField'), dxScroll: 90, dyScroll: -400}); await driver.execute('flutter:scroll', find.byType('ListView'), {dx: 50, dy: 100, durationMilliseconds: 200, frequency: 30}); await driver.execute('flutter:scrollIntoView', find.byType('TextField'), {alignment: 0.1}); - await driver.elementClick(find.byType('TextField')); // acquire focus - await driver.execute('flutter:enterText', 'I can enter text'); // enter text + await driver.elementSendKeys(find.byType('TextField'), 'I can enter text'); await driver.execute('flutter:waitFor', find.byText('I can enter text')); // verify text appears on UI await driver.elementClick(find.pageBack());