-
Notifications
You must be signed in to change notification settings - Fork 14
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
Update docs with guides on using matchers #902
Conversation
|
The preview packages of this pull request have been published. @bigtest/cliInstall using the following command: $ npm install @bigtest/cli@mk_matchers Or update your package.json file: {
"@bigtest/cli": "mk_matchers"
} @bigtest/interactorInstall using the following command: $ npm install @bigtest/interactor@mk_matchers Or update your package.json file: {
"@bigtest/interactor": "mk_matchers"
} @bigtest/serverInstall using the following command: $ npm install @bigtest/server@mk_matchers Or update your package.json file: {
"@bigtest/server": "mk_matchers"
} bigtest-sampleInstall using the following command: $ npm install bigtest-sample@mk_matchers Or update your package.json file: {
"bigtest-sample": "mk_matchers"
} |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work Min! I added some thoughts that come to mind
@cowboyd I'm trying to find an appropriate place in the Quick Start to include a matchers sneak peak but it feels to me that page goes over the big picture and matchers is more a micro feature. If we were to include it somehow, I could sneak them into either the We could add a sentence in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work y'all! it's looking great!! I left two questions/comments for your consideration. Thanks!
Link('Google').has({ | ||
href: or( | ||
'https://google.com', | ||
'https://twitter.com' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for the sake of making the example more realistic, maybe the second option could be https://google.ca
or another domain (which makes me wonder, can or
take an arbitrary amount of parameters?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change up the example however you'd like. Any specific reason for https://google.ca
?
or
can take more than two arguments:
These next three matchers: and(), or(), and not() are different from the first two matchers in that they can take multiple arguments and the arguments can be either a value or another matcher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason, just that a link to Google
probably has a google
href. How about this:
Link('Google').has({
href: or(
'https://google.com',
'https://google.co.uk',
'https://google.es'
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see what you're saying. We're straying off into an unrealistic example. However, I do like that the two are very different and it makes it easier to get the message across. If anybody is skimming through the docs, they might not notice the difference between .com
and .ca
.
So when we take this example:
Link('Google').has({
href: or(
'https://google.com',
'https://twitter.com'
)
})
It's very clear without any context that or()
is a conditional that only needs one condition to return true. The reader doesn't even need to remember the HTML layout to understand the example:
<a href="https://google.com">Google</a>
<a href="https://twitter.com">Twitter</a>
Whereas with:
Link('Google').has({
href: or(
'https://google.com',
'https://google.co.uk'
)
})
The reader might go "why not?" It's a silly example but matchers are used in complex situations. Because interactors are already so intuitive that the need for matchers would, I assume, be in special cases. Meaning I think it's appropriate to show unrealistic examples as long as it helps the readers understand how they work in the quickest way possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the example showing 3 TLDs. I think when there are three, it's easier to spot the difference. The other reason I like it is that I would not think to pass more than 2 parameters into this, and so it's teaching something useful about the API without introducing any new concepts/commentary.
This example is an opportunity to show off Frontside instead of google, potentially:
https://frontside.com/
https://www.frontside.com/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jorgelainfiesta For the or()
matcher we just need to illustrate that one false statement can still make a test pass because it's an either-or situation.
Link('Frontside').has({
href: or(
'frontside',
'frontside',
'frontside'
)
})
☝️ isn't as clear as:
Link('Frontside').has({
href: or(
'frontside',
'not-frontside'
)
})
Was the point I was trying to make.
And also do we actually add the different TLDs into the HTML example?
<a href="https://frontside.com">Frontside</a>
<a href="https://www.frontside.com">Frontside</a>
<a href="https://www.frontside.io">Frontside</a>
Because with only those three links, it's hard to discuss not()
- was the other argument I was making.
I suppose we could do frontside
and google
(just one of each) and still use the or
example with three different TLDs. 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that the HTML example could shoot show a single link, and the “or” matcher includes three different URLs. International TLDs is a more realistic example than frontside urls, but the frontside URLs get the job done too. I think either example works here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think the non-realistic example drives the point better of how or()
is used than using google.ca
and google.co.uk
.
Because if I was reading this, I'll be thinking, "why not just use href: including('google')
? what are the benefits of using or()
?". And in what real life scenario do we need to ensure that it's just one of the three of all the TLDs? It would make sense to use not()
if we wanted to specify that it should not be google.ca
.
So by doing or('google.com', 'twitter.com')
, I think we all know how silly the example is but we get the point much faster.
But anyway, I changed it. You can see the commit here. I didn't switch one of the links to Frontside yet because people will already be on the frontside website when they're reading this guide, and putting our Frontside link next to Google's might give off an inaccurate impression of how we perceive ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah gotcha, I see your point. Indeed including
would've been a better choice indeed. What is the use of or
then? I can't think of a use case but I guess there are plenty?
For me, reading incoherent examples is confusing. I'm like "why would they do that?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only real use case I saw was where someone wants to assert for a Button that may or may not be visible but still available in the DOM:
Button({ visibility: or(true, false) }).is(whatever);
So we could change all the examples for and
, or
, and not
so it uses a button instead but that boolean for visibility really only applies to or
so there's a lot of switching back and forth in the examples even if we use the same Button.
Like you mentioned below, let's just brush this off for now and update it later.
|
||
To create your own matcher without the use of any of the preexisting ones, you will need to create a function that returns a `{ match(), format() }` object. | ||
|
||
The `match()` function is where you place all of the matcher logic. It takes one argument, `actual`, which represents the values from the interactors. Here's how the `including()` matcher is implemented: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we be more specific. Instead of "the values from the interactors", actual will be the value of the locator or filter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
match()
function is where you place all of the matcher logic. It takes one argument,actual
, which will be the value of the locator or filter.
☝️ is this okay?
We pondered over this very sentence. The reasoning behind why I said "values" instead of being more specific is that in the context of creating your own matchers it doesn't make a difference whether "actual" is going to be a locator or filter value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cowboyd I'm going to assume the thumbs up are for the explanation for why I went with just "values". I'll resolve this for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
matchers are mentioned in the assertion section, but they can also be used anywhere you would pass a locator or a filter. That includes for finding. Do we emphasize this enough? I seem to recall an todo item to tease matchers in the section on filters and locators.
I believe we discussed including it in the quick start. I've pointed it out in the comment above. I also skimmed through the |
Regarding this last comment, I think putting matchers in their own file is the way to go here. Then you can show using matchers for assertions and other things, without trying to introduce the other concepts at the same time. Someone should already know what filters, assertions, etc. are. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great already! I'd ship it
Motivation
To update our docs with guides on how to use matchers. Resolves #824.
Approach
Here is the new
Assertions and Matchers
page, but I also had to make several changes to the previousLocators, Filters, and Actions
page so please read through both pages.TODOs
ShouldapplyMatcher()
be included in the guides? In discussing how one can write their own matchers, I show howincluding()
is implemented and provide agreaterThan()
example neither of which useapplyMatcher()
.Need to add a sneak peak example for matchers in the quick start page.Later?HTML
andFormField
to the builtin interactor list. #845 is on my TODOs list after this PR is finished.