Code Monkey home page Code Monkey logo

Comments (11)

aciccarello avatar aciccarello commented on July 17, 2024 9

I don't have much experience testing React but @jgwhite gave a talk recently at EmberConf that is related. I wonder if there is a good generalized aria-aware query library that could be used in tests across frameworks.

ember conf talk slide showing a "find control for label" test helper function

from react-testing-library.

jgwhite avatar jgwhite commented on July 17, 2024 5

@kentcdodds it is really really exciting (and also validating) to see you working on the same ideas. Iโ€™m starting work on a formal RFC for Emberโ€™s testing toolkit next week and Iโ€™ll be sure to reference this as prior art!

Thanks to @aciccarello for making the connection ๐Ÿ™Œ

from react-testing-library.

theKashey avatar theKashey commented on July 17, 2024 3

It always was a little problem - what to check and how to select.

  • data-testid is great, as long you could remove them in production.
  • aria- attributes is even better, as long they are describing an element
  • text matches? - awesome, cos check that user will see something expected - is the only thing you have to test.

Meanwhile

  • data-testid does not reflect that the customer will see. They are dead selectors.
  • aria- stuff shall not be used for testing purposes. Aria stuff should be used only to help browser understand or override the default behaviour.

If you need a button - use button, not role. Aria-disabled? Just disabled. In real it is a quite rare condition when you have to use aria, better use correct and semantic markup.

  • text content matches are not very specific, sometimes very flexible, sometimes you need that flexibility.

So - I could 90% agree with you. Text Content to test content, data-testid to test DOM structure, if you need to test it.
Just be a bit more careful with aria stuff. Do not prevent browser to infer the right behaviour by its own.

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024 3

You bring up good points @theKashey. I worry that if we start encouraging using aria- attributes, people will start slapping them on where they don't belong. If we do text matches, then I'd want our abstraction to be pretty loose (maybe allow for a regex search?).

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024 1

Alrighty, so I've written out a few utilities that have proven to be pretty useful and sensible. I think I want to put them in the library. I'm sure there are more (especially for more aria- attribute associations like the aria-labelledby one here). Feedback welcome:

function queryByLabelText(container, text, {selector = '*'} = {}) {
  const label = Array.from(container.querySelectorAll('label')).find(l =>
    matches(l.textContent, text),
  )
  if (!label) {
    return null
  }
  if (label.getAttribute('for')) {
    // <label for="someId">text</label><input id="someId" />
    return container.querySelector(`#${label.getAttribute('for')}`)
  } else if (label.getAttribute('id')) {
    // <label id="someId">text</label><input aria-labelledby="someId" />
    return container.querySelector(
      `[aria-labelledby="${label.getAttribute('id')}"]`,
    )
  } else if (label.children.length) {
    // <label>text: <input /></label>
    return label.querySelector(selector)
  }
  throw new Error(`cannot find associated element for label with text ${text}`)
}

function queryByText(container, text, {selector = '*'} = {}) {
  return Array.from(container.querySelectorAll(selector)).find(
    node => !node.children.length && matches(node.textContent, text),
  )
}

function queryByPlaceholder(container, text) {
  return Array.from(container.querySelectorAll('[placeholder]')).find(
    node =>
      node.getAttribute('placeholder') &&
      matches(node.getAttribute('placeholder'), text),
  )
}

function matches(textToMatch, matcher) {
  if (typeof matcher === 'string') {
    return textToMatch.toLowerCase().includes(matcher.toLowerCase())
  } else if (typeof matcher === 'function') {
    return matcher(textToMatch)
  } else {
    return matcher.test(textToMatch)
  }
}

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024 1

I'm almost finished with my implementation and improved FAQ/README recommendations. I think that tools which encourage improved practices (both for how we write tests as well as how we write applications) are really important and I'm excited by the future here. I'm also very surprised this isn't already mainstream. These ideas actually feel quite obvious...

from react-testing-library.

aciccarello avatar aciccarello commented on July 17, 2024 1

I'm glad to see connections made. I'd like to see this pattern brought into test Angular applications as well. ๐Ÿ‘ to everyone who has been working on this.

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024

I'm working on this right now, just FYI. We'll have several handy utilities for this stuff when I'm finished :)

from react-testing-library.

theKashey avatar theKashey commented on July 17, 2024

Iโ€™ll prefer to write the usage of a new stuff first.
Create some cases, and try to solve them with a better API and thus find that better API and the better practices.

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024

That's where these utilities came from. I'm applying them to tests in another project. It's cleaning things up nicely ๐Ÿ‘Œ

from react-testing-library.

kentcdodds avatar kentcdodds commented on July 17, 2024

Thanks for that link @aciccarello! @jgwhite that was a great talk! That's exactly what I'm trying to accomplish in this issue and your talk was very validating. Thank you!

from react-testing-library.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.