Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,31 @@ class _MainWidget extends StatelessWidget {
label: 'Input field with suffix @gmail.com',
child: const TextField(
key: Key('enabled text field'),
maxLines: null,
keyboardType: TextInputType.emailAddress,
autofillHints: <String>[AutofillHints.email],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Dart style guide, type arguments on collection literals should be omitted when they can be inferred from the context. Since autofillHints expects an Iterable<String>?, the <String> type argument is redundant.

Suggested change
autofillHints: <String>[AutofillHints.email],
autofillHints: [AutofillHints.email],
References
  1. Omit type arguments on generic collection literals when they can be inferred from the context. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the explicit to match the surrounding code, which uses explicit collection types throughout ([...]), and existing material_ui usage such as autofillHints: const [...] in text_form_field_test.dart.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the @gmail.com suffix, autofilling an email will show foo@gmail.com@gmail.com. Should we drop the suffix from these two fields, or is the suffix part of what this use case is meant to assess?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I reproduced it. Dropped the suffix in 0675f4b: a fixed suffix means the field only takes the part before the @, which conflicts with autocomplete="email". #/text-form-field has the same pattern, so I'll clean that up separately.

decoration: InputDecoration(
labelText: 'Email',
suffixText: '@gmail.com',
hintText: 'Enter your email',
// The field is single-line, so let the hint wrap at large
// text scales, one line per word.
hintMaxLines: 3,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PR description states that hintMaxLines: 5 is used to keep the hint wrapping at large text scales. However, the implementation uses hintMaxLines: 3. Consider changing this to 5 to align with the description and ensure sufficient headroom for wrapping at very large text scales, or update the PR description if 3 was chosen intentionally.

Suggested change
hintMaxLines: 3,
hintMaxLines: 5,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to 3 in description section.

),
),
),
Semantics(
label: 'Input field with suffix @gmail.com',
child: TextField(
key: const Key('disabled text field'),
maxLines: null,
keyboardType: TextInputType.emailAddress,
autofillHints: const <String>[AutofillHints.email],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Dart style guide, type arguments on collection literals should be omitted when they can be inferred from the context. Since autofillHints expects an Iterable<String>?, the <String> type argument is redundant.

Suggested change
autofillHints: const <String>[AutofillHints.email],
autofillHints: const [AutofillHints.email],
References
  1. Omit type arguments on generic collection literals when they can be inferred from the context. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the explicit to match the surrounding code, which uses explicit collection types throughout ([...]), and existing material_ui usage such as autofillHints: const [...] in text_form_field_test.dart.

decoration: const InputDecoration(
labelText: 'Email',
suffixText: '@gmail.com',
hintText: 'Enter your email',
// The field is single-line, so let the hint wrap at large
// text scales, one line per word.
hintMaxLines: 3,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PR description states that hintMaxLines: 5 is used to keep the hint wrapping at large text scales. However, the implementation uses hintMaxLines: 3. Consider changing this to 5 to align with the description and ensure sufficient headroom for wrapping at very large text scales, or update the PR description if 3 was chosen intentionally.

Suggested change
hintMaxLines: 3,
hintMaxLines: 5,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to 3 in description section.

),
enabled: false,
controller: TextEditingController(text: 'xyz'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ class _MainWidget extends StatelessWidget {
children: const <Widget>[
TextField(
key: Key('enabled password'),
autofillHints: <String>[AutofillHints.password],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Dart style guide, type arguments on collection literals should be omitted when they can be inferred from the context. Since autofillHints expects an Iterable<String>?, the <String> type argument is redundant.

Suggested change
autofillHints: <String>[AutofillHints.password],
autofillHints: [AutofillHints.password],
References
  1. Omit type arguments on generic collection literals when they can be inferred from the context. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the explicit to match the surrounding code, which uses explicit collection types throughout ([...]), and existing material_ui usage such as autofillHints: const [...] in text_form_field_test.dart.

decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
),
TextField(
key: Key('disabled password'),
autofillHints: <String>[AutofillHints.password],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Dart style guide, type arguments on collection literals should be omitted when they can be inferred from the context. Since autofillHints expects an Iterable<String>?, the <String> type argument is redundant.

Suggested change
autofillHints: <String>[AutofillHints.password],
autofillHints: [AutofillHints.password],
References
  1. Omit type arguments on generic collection literals when they can be inferred from the context. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping the explicit to match the surrounding code, which uses explicit collection types throughout ([...]), and existing material_ui usage such as autofillHints: const [...] in text_form_field_test.dart.

decoration: InputDecoration(labelText: 'Password'),
enabled: false,
obscureText: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,15 @@ void main() {
await tester.pumpAndSettle();
expect(findHeadingLevelOnes, findsOne);
});

testWidgets('password fields expose their input purpose', (WidgetTester tester) async {
await pumpsUseCase(tester, TextFieldPasswordUseCase());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To ensure the widget tree is fully built and settled before querying widgets or semantics, it is recommended to call await tester.pumpAndSettle() after pumping the use case, similar to how it is done in text_field_test.dart.

Suggested change
await pumpsUseCase(tester, TextFieldPasswordUseCase());
await pumpsUseCase(tester, TextFieldPasswordUseCase());\n await tester.pumpAndSettle();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test only reads EditableText.autofillHints, which is set once pumpWidget builds the tree, so there's nothing to settle. The other tests in this file query right after pumpsUseCase too. The email test settles because it checks semantics.


for (final key in <Key>[const Key('enabled password'), const Key('disabled password')]) {
final EditableText editableText = tester.widget<EditableText>(
find.descendant(of: find.byKey(key), matching: find.byType(EditableText)),
);
expect(editableText.autofillHints, contains(AutofillHints.password));
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' show SemanticsInputType;

import 'package:a11y_assessments/use_cases/text_field.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:material_ui/material_ui.dart';
Expand Down Expand Up @@ -71,4 +73,24 @@ void main() {
await tester.pumpAndSettle();
expect(findHeadingLevelOnes, findsOne);
});

testWidgets('email text fields expose their input purpose', (WidgetTester tester) async {
await pumpsUseCase(tester, TextFieldUseCase());
await tester.pumpAndSettle();

for (final key in <Key>[const Key('enabled text field'), const Key('disabled text field')]) {
final Finder finder = find.byKey(key);
// On web, a single-line field with the email input type renders an
// <input autocomplete="email">. A multiline field renders a <textarea>
// with autocomplete="off".
expect(
tester.getSemantics(finder),
containsSemantics(inputType: SemanticsInputType.email, isMultiline: false),
);
final EditableText editableText = tester.widget<EditableText>(
find.descendant(of: finder, matching: find.byType(EditableText)),
);
expect(editableText.autofillHints, contains(AutofillHints.email));
}
});
}
Loading