Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to Dart 3 #301

Draft
wants to merge 5 commits into
base: stable
Choose a base branch
from
Draft
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
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ topics:
- nps

environment:
sdk: ">=2.17.0 <4.0.0"
flutter: ">=3.0.0"
sdk: ">=3.0.0"
flutter: ">=3.10.0"

dependencies:
clock: ^1.1.0
Expand All @@ -36,7 +36,7 @@ dev_dependencies:
flutter_test:
sdk: flutter
lint: '>=1.10.0 <3.0.0'
spot: '>=0.3.1 <0.5.0'
spot: '^0.6.0'
test: ^1.21.0
transparent_image: ^2.0.0

Expand Down
8 changes: 4 additions & 4 deletions test/feedback_flow_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void main() {

// feedback is still available and not lost
await robot.openWiredash();
_larryPageView.spotSingleText('test message').existsOnce();
_larryPageView.spotText('test message').existsOnce();

// when discarding feedback
await robot.discardFeedback();
Expand All @@ -48,7 +48,7 @@ void main() {

// it is no longer available
await robot.openWiredash();
_larryPageView.spotSingleText('test message').doesNotExist();
_larryPageView.spotText('test message').doesNotExist();
});

testWidgets('Discard feedback disappears after 3s', (tester) async {
Expand All @@ -59,7 +59,7 @@ void main() {
await robot.discardFeedback();

final confirmDiscardButton =
_larryPageView.spotSingleText('l10n.feedbackDiscardConfirmButton');
_larryPageView.spotText('l10n.feedbackDiscardConfirmButton');
confirmDiscardButton.existsOnce();
await tester.pumpAndSettle(const Duration(seconds: 3));
confirmDiscardButton.doesNotExist();
Expand All @@ -74,7 +74,7 @@ void main() {
await robot.goToNextStep();
_larryPageView
.spot<Step1FeedbackMessage>()
.spotSingleText('l10n.feedbackStep1MessageErrorMissingMessage')
.spotText('l10n.feedbackStep1MessageErrorMissingMessage')
.existsOnce();

// Entering a message allows continue
Expand Down
110 changes: 54 additions & 56 deletions test/util/robot.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ class WiredashTestRobot {
}

Future<void> openWiredash() async {
final feedbackText = spotSingle<MaterialApp>().spotSingleText('Feedback')
final feedbackText = spotSingle<MaterialApp>().spotText('Feedback')
..existsOnce();
await _tap(feedbackText);
await act.tap(feedbackText);

// process the event, wait for backdrop to appear in the widget tree
await tester.pumpN(4);
Expand All @@ -149,10 +149,9 @@ class WiredashTestRobot {
}

Future<void> openPromoterScore() async {
final promoterScoreText = spotSingle<MaterialApp>()
.spotSingleText('Promoter Score')
..existsOnce();
await _tap(promoterScoreText);
final promoterScoreText =
spotSingle<MaterialApp>().spotText('Promoter Score')..existsOnce();
await act.tap(promoterScoreText);

// process the event, wait for backdrop to appear in the widget tree
await tester.pumpN(4);
Expand All @@ -179,9 +178,9 @@ class WiredashTestRobot {
_spotPageView.spotSingle<Step1FeedbackMessage>().existsOnce();
await tester.enterText(find.byType(TextField), message);
await tester.pumpAndSettle();
final button = spotSingle<TronButton>(
children: [spotSingleText('l10n.feedbackNextButton')],
);
final button = spotSingle<TronButton>()
.withChild(spotText('l10n.feedbackNextButton'))
.single;

// TODO find easier way to check if the button is clickable. Hit Testing?
await button.waitUntil(tester, (it) => it.isTappable(true));
Expand All @@ -193,10 +192,11 @@ class WiredashTestRobot {

Future<void> enterPromotionScoreMessage(String message) async {
final step = _spotPageView.spotSingle<PsStep2Message>()..existsOnce();
final done = step.spotSingle<TronButton>(
children: [spotSingleText('l10n.promoterScoreSubmitButton')],
)..existsOnce();
step.spotSingleText('l10n.promoterScoreBackButton').existsOnce();
final done = step
.spotSingle<TronButton>()
.withChild(spotText('l10n.promoterScoreSubmitButton'))
..existsOnce();
step.spotText('l10n.promoterScoreBackButton').existsOnce();
await tester.enterText(find.byType(TextField), message);
await tester.pumpAndSettle();

Expand All @@ -216,8 +216,8 @@ class WiredashTestRobot {
Future<void> skipScreenshot() async {
final step = _spotPageView.spotSingle<Step3ScreenshotOverview>()
..existsOnce();
await _tap(
step.spotSingleText('l10n.feedbackStep3ScreenshotOverviewSkipButton'),
await act.tap(
step.spotText('l10n.feedbackStep3ScreenshotOverviewSkipButton'),
);
await tester.pumpAndSettle();
await tester.pumpAndSettle();
Expand All @@ -234,18 +234,19 @@ class WiredashTestRobot {
/// Actually calling [FeedbackModel.submitFeedback]
Future<void> submitFeedback() async {
final step = _spotPageView.spotSingle<Step6Submit>()..existsOnce();
await _tap(
step.spot<TronButton>(
children: [step.spotSingleText('l10n.feedbackStep6SubmitSubmitButton')],
).last(),
await act.tap(
step
.spot<TronButton>()
.withChild(spotText('l10n.feedbackStep6SubmitSubmitButton'))
.last(),
);
print('submit feedback');
await tester.pump();
}

Future<void> skipEmail() async {
final step = _spotPageView.spotSingle<Step5Email>()..existsOnce();
await _tap(step.spotSingleText('l10n.feedbackNextButton'));
await act.tap(step.spotText('l10n.feedbackNextButton'));
await tester.pumpAndSettle();
await tester.pumpAndSettle();

Expand All @@ -255,7 +256,7 @@ class WiredashTestRobot {

Future<void> submitEmailViaButton() async {
final step = _spotPageView.spotSingle<Step5Email>()..existsOnce();
await _tap(step.spotSingleText('l10n.feedbackNextButton'));
await act.tap(step.spotText('l10n.feedbackNextButton'));
await tester.pumpAndSettle();

final newStatus = services.feedbackModel.feedbackFlowStatus;
Expand All @@ -272,7 +273,7 @@ class WiredashTestRobot {

Future<void> goToNextStep() async {
final oldStatus = services.feedbackModel.feedbackFlowStatus;
await _tap(spotSingleText('l10n.feedbackNextButton'));
await act.tap(spotText('l10n.feedbackNextButton'));
await tester.pumpAndSettle();
await tester.pumpAndSettle();
final newStatus = services.feedbackModel.feedbackFlowStatus;
Expand All @@ -281,13 +282,14 @@ class WiredashTestRobot {

Future<void> goToPrevStep() async {
final oldStatus = services.feedbackModel.feedbackFlowStatus;
final texts = spotTexts('l10n.feedbackBackButton');
final texts = spot<Text>()
.whereText((text) => text.equals('l10n.feedbackBackButton'));
final backdropStatus = services.backdropController.backdropStatus;

if (backdropStatus == WiredashBackdropStatus.centered) {
await _tap(texts.last());
await act.tap(texts.last());
} else {
await _tap(texts.first());
await act.tap(texts.first());
}

await tester.pumpAndSettle();
Expand All @@ -302,15 +304,15 @@ class WiredashTestRobot {
step.spot<Step3NoAttachments>().snapshot().discovered;
if (noAttachmentsResult.isNotEmpty) {
step.spot<Step3NoAttachments>().existsOnce();
final addScreenshotBtn = spotSingleText(
final addScreenshotBtn = spotText(
'l10n.feedbackStep3ScreenshotOverviewAddScreenshotButton',
);
await _tap(addScreenshotBtn);
await act.tap(addScreenshotBtn);
} else {
final gallery = step.spotSingle<Step3WithGallery>()..existsOnce();
final addAttachmentItem = gallery.spotSingle<NewAttachment>()
..existsOnce();
await _tap(addAttachmentItem);
await act.tap(addAttachmentItem);
}

await tester.waitUntil(find.byType(ScreenshotBar), findsOneWidget);
Expand All @@ -332,19 +334,19 @@ class WiredashTestRobot {

print('Take screeshot');
// Click the screenshot button
await _tap(
screenshotBar
.spotSingleText('l10n.feedbackStep3ScreenshotBarCaptureButton'),
await act.tap(
screenshotBar.spotText('l10n.feedbackStep3ScreenshotBarCaptureButton'),
);
while (services.feedbackModel.feedbackFlowStatus !=
FeedbackFlowStatus.screenshotDrawing) {
await tester.pumpHardAndSettle();
}

// Wait for active "Save" button
final nextButton = screenshotBar.spotSingle<TronButton>(
children: [spotSingleText('l10n.feedbackStep3ScreenshotBarSaveButton')],
).last();
final nextButton = screenshotBar
.spotSingle<TronButton>()
.withChild(spotText('l10n.feedbackStep3ScreenshotBarSaveButton'))
.last();

try {
await tester.waitUntil(nextButton.finder, findsOneWidget);
Expand All @@ -363,15 +365,15 @@ class WiredashTestRobot {
);
final screenshotBar = _spotBackdrop.spotSingle<ScreenshotBar>()
..existsOnce();
await _tap(
screenshotBar.spotSingleText('l10n.feedbackStep3ScreenshotBarSaveButton'),
await act.tap(
screenshotBar.spotText('l10n.feedbackStep3ScreenshotBarSaveButton'),
);
await tester.pumpHardAndSettle(const Duration(milliseconds: 100));

// wait until the animation is closed
await tester.waitUntil(
screenshotBar
.spotSingleText('l10n.feedbackStep3ScreenshotBarSaveButton')
.spotText('l10n.feedbackStep3ScreenshotBarSaveButton')
.finder,
findsNothing,
);
Expand All @@ -393,7 +395,7 @@ class WiredashTestRobot {
}

Future<void> selectLabel(String labelText) async {
await _tap(spotSingleText(labelText));
await act.tap(spotText(labelText));
await tester.pumpAndSettle();
}

Expand Down Expand Up @@ -423,7 +425,7 @@ class WiredashTestRobot {
)
.first();

await _tap(spotRatingCard(rating));
await act.tap(spotRatingCard(rating));
await tester.pumpAndSettle();

/// automatically goes to next step
Expand All @@ -434,9 +436,10 @@ class WiredashTestRobot {

Future<void> submitPromoterScore() async {
final step = _spotPageView.spotSingle<PsStep2Message>()..existsOnce();
final submitButton = step.spot<TronButton>(
children: [spotSingleText('l10n.promoterScoreSubmitButton')],
).last()
final submitButton = step
.spot<TronButton>()
.withChild(spotText('l10n.promoterScoreSubmitButton'))
.last()
..existsOnce();
final scrollable = spotSingle<LarryPageView>()
.spotSingle<StepPageScaffold>()
Expand All @@ -449,7 +452,7 @@ class WiredashTestRobot {
-100,
scrollable: scrollable.finder,
);
await _tap(submitButton);
await act.tap(submitButton);
await tester.pumpAndSettle();
print('submit Promoter Score');
}
Expand All @@ -461,20 +464,16 @@ class WiredashTestRobot {
}
}

Future<void> _tap(SingleWidgetSelector spot) async {
await tester.tap(spot.finder);
}

SingleWidgetSelector<Widget> get _discard =>
_spotPageView.spotSingleText('l10n.feedbackDiscardButton');
_spotPageView.spotText('l10n.feedbackDiscardButton');

SingleWidgetSelector<Widget> get _reallyDiscard =>
_spotPageView.spotSingleText('l10n.feedbackDiscardConfirmButton');
_spotPageView.spotText('l10n.feedbackDiscardConfirmButton');

/// Starts discarding feedback, call [confirmDiscardFeedback] to confirm
Future<void> discardFeedback() async {
_discard.existsOnce();
await _tap(_discard);
await act.tap(_discard);
await tester.pump();
_reallyDiscard.existsOnce();
}
Expand All @@ -483,7 +482,7 @@ class WiredashTestRobot {
Future<void> confirmDiscardFeedback() async {
_discard.doesNotExist();
_reallyDiscard.existsOnce();
await _tap(_reallyDiscard);
await act.tap(_reallyDiscard);
await tester.pump();
}
}
Expand Down Expand Up @@ -588,7 +587,7 @@ extension on Symbol {
}
}

extension SpotWaitUntil<W extends Widget> on SingleWidgetSelector<W> {
extension SpotWaitUntil<W extends Widget> on WidgetSelector<W> {
Future<void> waitUntil(
WidgetTester tester,
void Function(SingleWidgetSnapshot<W>) matcher, {
Expand All @@ -600,7 +599,7 @@ extension SpotWaitUntil<W extends Widget> on SingleWidgetSelector<W> {
while (true) {
attempt++;

final snapshot = this.snapshot();
final snapshot = single.snapshot();

final Object error;
final StackTrace stack;
Expand Down Expand Up @@ -645,10 +644,9 @@ extension SpotWaitUntil<W extends Widget> on SingleWidgetSelector<W> {
extension EffectiveTextMatcher on WidgetMatcher<TronButton> {
WidgetMatcher<TronButton> isTappable(bool value) {
return hasProp(
selector: (subject) => subject.context.nest<bool>(
widgetSelector: (subject) => subject.context.nest<bool>(
() => ['is clickable"'],
(Element element) {
final widget = element.widget as TronButton;
(TronButton widget) {
return Extracted.value(widget.onTap != null);
},
),
Expand Down