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

feat(timeout): allow to configure the timeout for queries #7

Merged
merged 2 commits into from Jun 2, 2018

Conversation

npeterkamps
Copy link
Collaborator

@npeterkamps npeterkamps commented May 26, 2018

What:

Make timeout configurable for all query functions through the options object. (Issue #6)

Why:

So I don't need to use cy.wait() to prevent timeouts from happening.

How:

  • use timeout from the options object
  • make sure that Cypress' timeout is larger, so our error message is used
  • make sure Cypress' Command Log doesn't get cluttered when options isn't specified

Other changes

  • show example in the docs
  • updated outdated snapshot
  • ignore .idea folder (JetBrains IDE's)
  • added myself to contributers at the request of the contribution guide

Question:

Should I add something in the tests to test the timeout? Like some JS code in the html file to dynamically add an element after a certain time?

Checklist:

  • Documentation
  • Tests
  • Ready to be merged
  • Added myself to contributors table

- make sure that Cypress' timeout is larger, so our error message is used
- make sure Cypress' Command Log doesn't get cluttered when options isn't specified
- show example in the docs
- updated outdated snapshot
- ignore .idea folder (JetBrains IDE's)
- added myself to contributers at the request of the contribution guide
Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

Looks good to me!

src/index.js Outdated
const queryImpl = queries[queryName]
const baseCommandImpl = doc =>
waitForElement(() => queryImpl(doc, ...args), {
waitForElement(() => queryImpl(doc, text, options), {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This call isn't quite safe. What if queryImpl takes other set of arguments, not just text followed by options? The original idea was to propagate all the query options verbatim to queryImpl. I would consider queryImpl.length (the function arity) to see how many arguments it actually takes, and passed the respective slice of args to it; if there's one more argument remaining, that's our Cypress command options with timeout and potentially other stuff such as log: false.

Relying on function arity may be unreliable if the queryImpl uses variable number of ...args (i.e. arguments) instead of defining all arguments explicitly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. However, I prefer to have a single options object, so there's no need to keep in mind which options go into which object. Do you agree?

Copy link
Member

Choose a reason for hiding this comment

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

I prefer the ...args for stuff like this if we can get away with it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would consider queryImpl.length (the function arity) to see how many arguments it actually takes, and passed the respective slice of args to it; if there's one more argument remaining, that's our Cypress command options with timeout and potentially other stuff such as log: false.

So if I understand this correctly, the function arity of our command function is the function arity of the query function + 1, right?
If the query function takes two arguments; text and options and options is optional, you'd have to pass in ("text", undefined, { timeout: 10000 }) to set a timeout?

I prefer the API to have a single options object. For that to work and still use ...args, we'd have to make the assumption that the options parameter is the last argument. In that case, I can retrieve it using args[args.length -1] and destructure it like already in the PR. So I agree that ...args is better, but I think the command function shouldn't have an extra options object just for the Cypress related options. What are your thoughts on that?

Copy link
Member

Choose a reason for hiding this comment

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

Honestly I don't care all that much. Let's just go with what you have here and we can change it in the future if it needs changing. I think I'm good with this PR as-is :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay, whatevs. I'm just saying that queryImpl is not guaranteed to be that generic to always take (doc, text, options).

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm... I think that's right. In that case, below where we're using text and options in message, do we need to make that more generic somehow to support different APIs?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm... I think that's right. In that case, below where we're using text and options in message, do we need to make that more generic somehow to support different APIs?

Yes, that, too. There was a generic solution before: just pass all the args for message (Cypress can handle arrays in the message as far as I remember).

@kentcdodds
Copy link
Member

Rats. The build is failing and I don't know why. I don't have time to look into it. Could you figure out what's going on?

@kentcdodds
Copy link
Member

I'm going out of town for all week so I probably wont be able to merge this myself. @sompylasar, I think you have merge rights so if you want to merge this once the build is fixed that would be splendid :)

@npeterkamps
Copy link
Collaborator Author

I don't know what's going on either. It works locally. Problem persisted after I forced Travis to try and build it again...

@sompylasar
Copy link
Collaborator

Travis log says Cypress cannot connect to the app server that it has to run the tests against.

[lint] npm run lint --silent exited with code 0
�7[test] It looks like this is your first time using Cypress: 2.1.0
[test] 
[test] [15:27:30]  Verifying Cypress can run /home/travis/build/kentcdodds/cypress-testing-library/node_modules/cypress/dist/Cypress [started]
[test]  PASS  src/__tests__/add-commands.js
[test]  PASS  src/__tests__/commands.js
[test] 
[test] Test Suites: 2 passed, 2 total
[test] Tests:       2 passed, 2 total
[test] Snapshots:   1 passed, 1 total
[test] Time:        5.148s
[test] Ran all test suites.
[test] [15:27:32]  Verifying Cypress can run /home/travis/build/kentcdodds/cypress-testing-library/node_modules/cypress/dist/Cypress [completed]
[test] 
[test] Opening Cypress...
[test] Cypress could not verify that the server set as your 'baseUrl' is running:
[test] 
[test]   > http://localhost:13370
[test] 
[test] Your tests likely make requests to this 'baseUrl' and these tests will fail if you don't boot your server.
[test] 
[test] Please start this server and then run Cypress again.
[test] npm run test --silent exited with code 1
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! cypress-testing-library@0.0.0-semantically-released validate: `kcd-scripts validate build,lint,test`
npm ERR! Exit status 1

@sompylasar
Copy link
Collaborator

I believe the Travis failure is unrelated to this PR's changes, but it's understandable:

  "test:cypress": "npm-run-all --silent --parallel --race test:cypress:serve test:cypress:run",

— this line does not guarantee that test:cypress:run starts after test:cypress:serve has started listening, so there are race conditions, depends on how quick things happen in parallel in both processes.

@sompylasar
Copy link
Collaborator

We can use https://www.npmjs.com/package/wait-port (don't forget to npm i --save-dev wait-port) in test:cypress:run prior to starting Cypress.

"test:cypress:run": "wait-port -t 10000 localhost:13370 && cypress run",

@kentcdodds
Copy link
Member

I'll merge this, but it won't release if the build isn't working so we will want to get that done asap.

@kentcdodds kentcdodds merged commit ec3b712 into testing-library:master Jun 2, 2018
@kentcdodds
Copy link
Member

🎉 This PR is included in version 2.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@npeterkamps npeterkamps deleted the pr/timeout branch June 2, 2018 20:33
kentcdodds pushed a commit that referenced this pull request Dec 31, 2018
<!--
Thanks for your interest in the project. Bugs filed and PRs submitted are appreciated!

Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Also, please make sure you're familiar with and follow the instructions in the
contributing guidelines (found in the CONTRIBUTING.md file).

If you're new to contributing to open source projects, you might find this free
video course helpful: http://kcd.im/pull-request

Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!
-->

<!-- What changes are being made? (What feature/bug is being fixed here?) -->

**What**:

This change adds TypeScript support for the `timeout` matcher option introduced in #7.

<!-- Why are these changes necessary? -->

**Why**:

Currently, `cypress-testing-library` uses the `MatcherOptions` interface directly from `dom-testing-library`, which does not have a `timeout` property (`timeout` is unique to `cypress-testing-library`), so using the `timeout` option throws a type error.

![image](https://user-images.githubusercontent.com/1288694/50553888-bf2ee180-0c6d-11e9-9250-a8c00c0db833.png)


<!-- How were these changes implemented? -->

**How**:

I introduced a new `CTLMatcherOptions` interface for `cypress-testing-library` specific matcher options, aliased the `MatcherOptions` import from `dom-testing-library` to `DTLMatcherOptions`, and created a new type `MatcherOptions`, a union of the two. I also added `timeout` to the existing typings test (which fails without this change).

<!-- Have you done all of these things?  -->

**Checklist**:

<!-- add "N/A" to the end of each line that's irrelevant to your changes -->

<!-- to check an item, place an "x" in the box like so: "- [x] Documentation" -->

* [ ] Documentation
* [x] Tests
* [x] Ready to be merged <!-- In your opinion, is this ready to be merged as soon as it's reviewed? -->
* [x] Added myself to contributors table <!-- this is optional, see the contributing guidelines for instructions -->

<!-- feel free to add additional comments -->

**Additional Information**:

The build was failing because the commands snapshot was outdated (new commands were added to `dom-testing-library` more recently than `cypress-testing-library` has been built on CI). I fixed the snapshot in this PR so I could progress, but let me know if you'd prefer that be separated out in its own PR and I'll split them up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants