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

Classifier: Refactor survey task tests #3933

Merged
merged 18 commits into from
Dec 6, 2022
Merged

Conversation

mcbouslog
Copy link
Contributor

@mcbouslog mcbouslog commented Nov 30, 2022

Package

  • lib-classifier

Describe your changes

  • refactor survey task tests for when choice with required questions selected
  • refactor some (not all, left at least one test with getByRole for related component) tests with getByText instead of getByRole
  • improves SurveyTask.spec.js tests runtime by approximately 4 seconds

How to Review

Helpful explanations that will make your reviewer happy:

  • What Zooniverse project should my reviewer use to review UX?
  • What user actions should my reviewer step through to review this PR?
  • Which storybook stories should be reviewed?
  • Are there plans for follow up PR’s to further fix this bug or develop this feature?

Checklist

PR Creator - Please cater the checklist to fit the review needed for your code changes.
PR Reviewer - Use the checklist during your review. Each point should be checkmarked or discussed before PR approval.

General

  • Tests are passing locally and on Github
  • Documentation is up to date and changelog has been updated if appropriate
  • You can yarn panic && yarn bootstrap or docker-compose up --build and FEM works as expected
  • FEM works in all major desktop browsers: Firefox, Chrome, Edge, Safari (Use Browserstack account as needed)
  • FEM works in a mobile browser

Refactoring

  • The PR creator has described the reason for refactoring
  • The refactored component(s) continue to work as expected

@mcbouslog mcbouslog added the tests Related to unit tests, integration tests, etc label Nov 30, 2022
@mcbouslog mcbouslog added the experiment Something to try out and gather more information on label Nov 30, 2022
@coveralls
Copy link

coveralls commented Nov 30, 2022

Coverage Status

Coverage increased (+0.3%) to 82.478% when pulling 158d3be on survey-task-tests-refactor into 103fc15 on master.

Copy link
Contributor

@eatyourgreens eatyourgreens left a comment

Choose a reason for hiding this comment

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

Is there a reason that you’re not using screen to run queries?

Buttons and other labelled elements should use getByLabelText rather than getByText.

@eatyourgreens
Copy link
Contributor

eatyourgreens commented Nov 30, 2022

A couple of other thoughts:

  • within can help to narrow the scope of a query eg. only look for menu items inside a menu. That could speed queries up.
  • you also have fast APIs like querySelector and querySelectorAll to find DOM nodes for testing.
  • you can use beforeEach to reduce repetition in test blocks.
  • caching query results with a variable is faster than rebuilding the DOM and finding them again, when you want to test multiple elements on the same screen.

Copy link
Contributor

@eatyourgreens eatyourgreens left a comment

Choose a reason for hiding this comment

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

Don’t use ARIA labels to duplicate button labels.

Copy link
Contributor

@eatyourgreens eatyourgreens left a comment

Choose a reason for hiding this comment

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

Why has the Identify button label been changed to 'Identify Aardark', 'Identify Fire' etc? It should be 'Identify' for any choice.

@mcbouslog
Copy link
Contributor Author

lib-react-components and Grommet buttons (Primary, Button, etc.) that define the label as a property on the component are not found with getByLabelText. If the noted buttons have an a11yTitle they are found with getByLabelText.

Components that are found with getByLabelText:

Components with defined labels that aren't found with getByLabelText:

@eatyourgreens
Copy link
Contributor

Is that because you're looking for eg. SurveyTask.Choice.identify but the label is 'Identify'?

@eatyourgreens
Copy link
Contributor

eatyourgreens commented Dec 2, 2022

No wait, the docs say this:

The example above does NOT find the input node for label text broken up by elements.

https://testing-library.com/docs/queries/bylabeltext#name

So those buttons could be failing because they use HTML markup in their labels. ChoiceButton here, for example, has markup in its label, because it uses images.

ChoiceButton there, by the way, should not have an ARIA label. A button should either have a text label:

<button>Text label</button>

or an ARIA label:

<button aria-label="Text label"><img /></button>

but never both together.

To be honest, in that second case the button label should be image alt text.

<button><img alt="Text label" /></button>

@mcbouslog
Copy link
Contributor Author

mcbouslog commented Dec 2, 2022

For buttons with HTML markup in the labels, preventing use of getByLabelText, what do you think is the preferred query? I think ideally it'd be getByRole('button', { name: 'Aardvark' }), but that query takes awhile, so maybe for these tests getByText?

@eatyourgreens
Copy link
Contributor

eatyourgreens commented Dec 3, 2022

This query will find all menu item checkboxes inside the first menu on the page. It should be fast too.

querySelector([role=“menu”]).querySelectorAll([role=“menuitemcheckbox”])

If the checkboxes have values, you can further refine the query with [value=“Aardvark”]. Otherwise, you could pluck the first item from the returned NodeList, or filter the node list by inspecting the text of each element to find a particular button.

Stepping back from specific tests, is the run time being spent rendering the survey task, or running queries? If it’s rendering excessively, you can cache rendered nodes in variables, as snapshots of the DOM state, and reuse them.

eg.

const choicesMenu = document.querySelector([role=“menu”])

const choiceButtons = choiceMenu.querySelectorAll([role=“menuitemcheckbox”])

/*
 Reuse choiceMenu and choiceButtons
 to save time later. 
*/

const aardvarkButton = Array.from(choiceButtons).find(button => button.textContent === ‘Aardvark’)

Have a look at the Classifier tests, which do this because they are also slow. The Classifier tests are also split into two files, to speed them up a bit, so consider that too.

@github-actions github-actions bot added the approved This PR is approved for merging label Dec 3, 2022
@eatyourgreens
Copy link
Contributor

@eatyourgreens
Copy link
Contributor

Also noting here that ChoiceButton, linked above, wraps a div with button, which is invalid HTML.

@mcbouslog mcbouslog force-pushed the survey-task-tests-refactor branch from 667d4f1 to 747242a Compare December 6, 2022 00:39
@eatyourgreens eatyourgreens force-pushed the survey-task-tests-refactor branch from 747242a to dbb1864 Compare December 6, 2022 11:15
@eatyourgreens
Copy link
Contributor

eatyourgreens commented Dec 6, 2022

This is running a lot faster now on my laptop, though the excessive rendering is still making it quite slow.

I've rebased and added a commit that renders a story once, in a before() block, then tests the output DOM of that story in separate it() blocks. You can use that as an example to speed up the other test blocks. There are a lot of tests where you run the same render multiple times. You might be able to run it once, store the output in variables then test each of those variables in it() blocks. I think the only places where you do need to re-render from scratch are tests where you're running a specific sequence of interactions inside an it(), changing the state of the component and testing that as you go.

I also fixed a bug in the 'Clear FIlters' button, which had the wrong label text. Your tests had caught the bug, but you'd updated the tests to pass by using the broken label, rather than fixing the button so that it passed with the expected label.

@eatyourgreens
Copy link
Contributor

CI isn't timing out, so I'm happy for this to be merged as-is.

@eatyourgreens eatyourgreens force-pushed the survey-task-tests-refactor branch from dbb1864 to 5b489fc Compare December 6, 2022 11:34
- Render once, then test rendered output in individual `it()` blocks.
- Fix alt text for Clear Filters button.
@eatyourgreens eatyourgreens force-pushed the survey-task-tests-refactor branch from 5b489fc to 8ce1935 Compare December 6, 2022 12:05
@eatyourgreens
Copy link
Contributor

I still can't figure out how to remove a filter, in the storybook, using only the keyboard. Definitely check that the user interactions in the keyboard tests match what a real volunteer would be expected to do. I have a feeling we're baking bad UX into the tests, which means they'll fail when the UX failure is fixed.

@mcbouslog
Copy link
Contributor Author

mcbouslog commented Dec 6, 2022

Thank you @eatyourgreens ! I'll merge this shortly.

For SurveyTask.spec.js,

  • before these changes:

0_master

  • with these changes:

11_identify_data-testid

Adding data-testid to the identify button and reducing the tabs to select a required choice question answer cut the related longest running test from 1661ms to 513ms for me locally.

The filters can be removed by tabbing to the close/remove button within the filter and pressing space or enter. I can record a video and share on Slack if it'd be helpful. Regardless, I think the filters need a substantive refactor as noted in #3919. I'm about to add a comment in that issue to further discuss.

@eatyourgreens
Copy link
Contributor

The filters can be removed by tabbing to the close/remove button within the filter and pressing space or enter.

This is a bug. See #3919. Tab on each radio button should take you out of the radio button group and on to the next focusable element on the page.

@eatyourgreens
Copy link
Contributor

FWIW, I'm toggling the selected radio button with the cursor keys, then trying Space or Enter to clear the selected value.

@mcbouslog mcbouslog merged commit 921e992 into master Dec 6, 2022
@mcbouslog mcbouslog deleted the survey-task-tests-refactor branch December 6, 2022 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved This PR is approved for merging experiment Something to try out and gather more information on tests Related to unit tests, integration tests, etc
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants