Skip to content

False positive for _createPartialCoverageMessage #120

@MaxLap

Description

@MaxLap

(This is in spot 0.18)

I believe that right now, the code for _findPokablePositions is subject to floating point errors (things like 0.1 + 0.2 not being == to 0.3).

Running the test at the bottom of this post triggers this warning (At least on my computer):

Warning: The 'RichText' is only partially reacting to tap events. Only ~67% of the widget reacts to hitTest events.

Possible causes:
 - The widget is partially positioned out of view
 - It is covered by another widget.
 - It is too small (<8x8)

Possible solutions:
 - Scroll the widget into view using act.dragUntilVisible()
 - Make sure no other Widget is overlapping on small screens
 - Increase the Widget size

If I shorten the "Deleting this transaction will remove it for everyone it's impact on the balances." to just "Deleting this transaction", the warning goes away.

If instead of shortening the warning, I edit _findPokablePositions to add some 0.01 to the calculations:

  for (int x = 0; x < renderBox.size.width; x += gridSize) {
    for (int y = 0; y < renderBox.size.height; y += gridSize) {
      final Offset localPosition = Offset(x.toDouble()+0.01, y.toDouble()+0.01);

The warning also goes away.

When running my test-suite, I noticed that I had 2 other cases where the "Pokability" was below 100%. Changing to the +0.01 strategy made all of them be at 100%.

To me, it really all sounds like since the code is currently testing at the exact edge, sometimes, the float imprecision issue strikes and trigger a false positive. Since the warning also cannot be disabled, this is quite annoying.

There may be other / better solutions. I can make a PR based on this idea if you want. If so, do you want me to add the test at the bottom as a test in spot?

Here is the test (I just reduced an actual case I had):

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:spot/spot.dart';

void main() {
  setUp(() async {
    await loadAppFonts();
  });

  group('end-to-end test', () {
    testWidgets('Create transactions with most features', (WidgetTester tester) async {
      tester.view.devicePixelRatio = 2.625;
      tester.view.physicalSize = Size(1080, 2400);
      await tester.pumpWidget(MaterialApp(theme: ThemeData(useMaterial3: true), home: TheThing()));
      await tester.pumpAndSettle();

      await act.tap(spotText("BUTTON"));
      await tester.pumpAndSettle();

      await act.tap(spotText("Yes").first());
      await tester.pumpAndSettle();
    });
  });
}

class TheThing extends StatelessWidget {
  const TheThing({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TextButton(
        child: Text("BUTTON"),
        onPressed: () async {
          await showDialog<bool>(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text('Delete transaction'),
                content: const SingleChildScrollView(
                  child: ListBody(
                    children: <Widget>[
                      // Shortening this text enough sometimes remove the warning
                      Text("Deleting this transaction will remove it for everyone it's impact on the balances."),
                      Text('Are you sure you want to delete it?'),
                    ],
                  ),
                ),
                actions: <Widget>[
                  TextButton(child: const Text('Yes'), onPressed: () async {}),
                  TextButton(child: const Text('No'), onPressed: () {}),
                ],
              );
            },
          );
        },
      ),
    );
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions