Unverified Commit c94f0bea authored by David Iglesias's avatar David Iglesias Committed by GitHub

[web] Make web integration tests shadow DOM aware. (#82926)

parent fa1c6a28
......@@ -904,6 +904,7 @@ Future<void> _runFlutterDriverWebTest({
await runCommand(
flutter,
<String>[
...?flutterTestArgs,
'drive',
'--target=$target',
'--browser-name=chrome',
......@@ -1080,6 +1081,7 @@ Future<void> _runGalleryE2eWebTest(String buildMode, { bool canvasKit = false })
await runCommand(
flutter,
<String>[
...?flutterTestArgs,
'drive',
if (canvasKit)
'--dart-define=FLUTTER_WEB_USE_SKIA=true',
......@@ -1163,6 +1165,7 @@ Future<void> _runWebReleaseTest(String target, {
await runCommand(
flutter,
<String>[
...?flutterTestArgs,
'build',
'web',
'--release',
......
......@@ -15,6 +15,15 @@ import 'package:web_e2e_tests/text_editing_main.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
/// Locate elements in the correct root of the application, whether it is
/// `document` or the new `shadowRoot` of `flt-class-pane`.
List<Node> findElements(String selector) {
final ShadowRoot? shadowRoot = document.querySelector('flt-glass-pane')?.shadowRoot;
return (shadowRoot != null) ?
shadowRoot.querySelectorAll(selector):
document.querySelectorAll(selector);
}
testWidgets('Focused text field creates a native input element',
(WidgetTester tester) async {
app.main();
......@@ -29,10 +38,9 @@ void main() {
await tester.tap(find.byKey(const Key('input')));
// A native input element will be appended to the DOM.
final List<Node> nodeList = document.getElementsByTagName('input');
final List<Node> nodeList = findElements('input');
expect(nodeList.length, equals(1));
final InputElement input =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input = nodeList[0] as InputElement;
// The element's value will be the same as the textFormField's value.
expect(input.value, 'Text1');
......@@ -57,10 +65,9 @@ void main() {
await tester.tap(find.byKey(const Key('empty-input')));
// A native input element will be appended to the DOM.
final List<Node> nodeList = document.getElementsByTagName('input');
final List<Node> nodeList = findElements('input');
expect(nodeList.length, equals(1));
final InputElement input =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input = nodeList[0] as InputElement;
// The element's value will be empty.
expect(input.value, '');
......@@ -92,8 +99,7 @@ void main() {
await tester.tap(find.byKey(const Key('input2')));
// // Press Tab. This should trigger `onFieldSubmitted` of TextField.
final InputElement input =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input = findElements('input')[0] as InputElement;
dispatchKeyboardEvent(input, 'keydown', <String, dynamic>{
'keyCode': 13, // Enter.
'cancelable': true,
......@@ -121,10 +127,9 @@ void main() {
await tester.tap(find.byKey(const Key('input')));
// A native input element will be appended to the DOM.
final List<Node> nodeList = document.getElementsByTagName('input');
final List<Node> nodeList = findElements('input');
expect(nodeList.length, equals(1));
final InputElement input =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input = nodeList[0] as InputElement;
// Press Tab. The focus should move to the next TextFormField.
dispatchKeyboardEvent(input, 'keydown', <String, dynamic>{
......@@ -132,14 +137,14 @@ void main() {
'code': 'Tab',
'bubbles': true,
'cancelable': true,
'composed': true,
});
await tester.pumpAndSettle();
// A native input element for the next TextField should be attached to the
// DOM.
final InputElement input2 =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input2 = findElements('input')[0] as InputElement;
expect(input2.value, 'Text2');
}, semanticsEnabled: false);
......@@ -156,10 +161,9 @@ void main() {
await tester.tap(find.byKey(const Key('input')));
// A native input element will be appended to the DOM.
final List<Node> nodeList = document.getElementsByTagName('input');
final List<Node> nodeList = findElements('input');
expect(nodeList.length, equals(1));
final InputElement input =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input = nodeList[0] as InputElement;
// Press and release CapsLock.
dispatchKeyboardEvent(input, 'keydown', <String, dynamic>{
......@@ -167,12 +171,14 @@ void main() {
'code': 'CapsLock',
'bubbles': true,
'cancelable': true,
'composed': true,
});
dispatchKeyboardEvent(input, 'keyup', <String, dynamic>{
'key': 'CapsLock',
'code': 'CapsLock',
'bubbles': true,
'cancelable': true,
'composed': true,
});
// Press Tab. The focus should move to the next TextFormField.
......@@ -181,14 +187,14 @@ void main() {
'code': 'Tab',
'bubbles': true,
'cancelable': true,
'composed': true,
});
await tester.pumpAndSettle();
// A native input element for the next TextField should be attached to the
// DOM.
final InputElement input2 =
document.getElementsByTagName('input')[0] as InputElement;
final InputElement input2 = findElements('input')[0] as InputElement;
expect(input2.value, 'Text2');
}, semanticsEnabled: false);
......@@ -216,7 +222,7 @@ void main() {
await gesture.up();
// A native input element will be appended to the DOM.
final List<Node> nodeList = document.getElementsByTagName('textarea');
final List<Node> nodeList = findElements('textarea');
expect(nodeList.length, equals(1));
final TextAreaElement input = nodeList[0] as TextAreaElement;
// The element's value should contain the selectable text.
......
......@@ -8,6 +8,8 @@ import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
import 'package:webdriver/async_io.dart';
// TODO(web): Migrate this test to a normal integration_test with a WidgetTester.
/// The following test is used as a simple smoke test for verifying Flutter
/// Framework and Flutter Web Engine integration.
void main() {
......@@ -35,12 +37,23 @@ void main() {
await Future<void>.delayed(const Duration(seconds: 2));
// A flutter web app may be rendered directly on the body of the page, or
// inside the shadow root of the flt-glass-pane (after Flutter 2.4). To
// make this test backwards compatible, we first need to locate the correct
// root for the app.
//
// It's either the shadowRoot within flt-glass-pane, or [driver.webDriver].
final SearchContext appRoot = await driver.webDriver.execute(
'return document.querySelector("flt-glass-pane")?.shadowRoot;',
<dynamic>[],
) as SearchContext? ?? driver.webDriver;
// Elements with tag "flt-semantics" would show up after enabling
// accessibility.
//
// The tag used here is based on
// https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/semantics/semantics.dart#L534
final WebElement element = await driver.webDriver.findElement(const By.tagName('flt-semantics'));
final WebElement element = await appRoot.findElement(const By.cssSelector('flt-semantics'));
expect(element, isNotNull);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment