bigtestjs / interactor Goto Github PK
View Code? Open in Web Editor NEWAll BigTest development has moved to https://github.com/thefrontside/bigtest
Home Page: https://github.com/thefrontside/bigtest
License: MIT License
All BigTest development has moved to https://github.com/thefrontside/bigtest
Home Page: https://github.com/thefrontside/bigtest
License: MIT License
Looking over a recent fix for these docs, I realized that the example is actually incorrect. The find
property creator returns a getter, so the example should not be .getHeader()
, but .header
instead.
Given these interactors:
@interactor class SignInInteractor {
fillName = fillable('[data-test-name-input]')
fillEmail = fillable('[data-test-email-input]')
submit = clickable('[data-test-submit]')
fillAndSubmit(name, email) {
return this
.fillName(name)
.fillEmail(email)
.submit()
}
}
@interactor class PageInteractor {
signInForm = new SignInInteractor('[data-test-signin-form]')
}
I would expect this to work:
new PageInteractor()
.signInForm.fillAndSubmit('Wil', '[email protected]')
But instead, an error is throw that might look like this:
PageInteractor.fillEmail is not a function
This is because when an interactor is nested, it's methods return new instances of the parent interactor. So fillName()
in SignInInteractor
will return a new PageInteractor
.
We should have a way to break out of this nested structure for complex methods such as this. Something like this.pure()
, this.scoped()
, or something akin to return an un-nested interactor.
The links in the README currently point to the old frontside mono repo. We should update them to the packages that live on this org now.
It's not obvious that there are default properties on an interactor like isVisible
. If you set a property on an interactor with the same key you'll get an error like:
Uncaught Error: cannot redefine existing property "isVisible"
In an ideal world we should throw an error saying something like "Interactor already has a property named isVisible
, please choose a new name"
Or something that says that interactor provides this. I spent ~5 mins looking for a duplicate until I realized what was going on.
import { setupAppForTesting } from '@bigtest/react';
import {
Interactor,
clickable, fillable, blurrable
} from '@bigtest/interactor';
import Application from '@ui/application';
class TodoMVCPage extends Interactor {
clickFirstTodo = clickable('ul.todo-list li:first-child');
fillName = fillable('ul.todo-list li:first-child input');
}
describe('Acceptance | todo editing', () => {
let app;
beforeEach(async () => {
app = await setupAppForTesting(Application);
});
it('the initial todo can be edited', () => {
const page = new TodoMVCPage()
.clickFirstTodo();
const edits = app.find('.editable');
const classes = edits[0].classList;
expect(classes).to.contain('editing');
});
and then I get this error:
1) Acceptance | todo editing
the initial todo can be edited:
ReferenceError: Element is not defined
at new Interactor (node_modules/@bigtest/interactor/dist/umd/index.js:855:59)
at new TodoMVCPage (tests/acceptance/todo-editing-test.ts:8:9)
at Context.it (tests/acceptance/todo-editing-test.ts:25:18)
at <anonymous>
It is common in a webpack environment when using babel to not transform modules within the node_modules
directory. Our package's "module"
field points directly to the src
files, which are typically compiled with @babel/preset-env
. When babel is configured to not compile our packages within node_modules
, bundles that use our packages can end up broken.
This can be seen in @bigtest/interaction
tests by removing the (!?/@bigtest)
regexp within the babel-loader
exclude option in the karma.config.js
file. This causes the package to fail to properly extend the convergence class and thereby causes every test to fail.
(moved from thefrontside/bigtest#55)
Originally, the interactors were published under the @bigtest/interaction
package.
We accidentally installed it and were . We should probably publish a version with a deprecation message like
"DID YOU MEAN @bigtest/interactor`?
On an app using CSS Modules, what should be the strategy for using the hasClass()
page object property?
Import the CSS file with the style into the page object as styles
so you can check for hasClass(styles.hasError, '#idThatWouldHaveError')
.
Modify hasClass()
to accept a regex as the className
- that way a class .hasError--{hash}
can be found with hasClass('^has-Error--.*$', '#idThatWouldHaveError')
.
Option 1 seems more bulletproof, but should page objects be dealing with CSS like that? Option 2 would be a nice option, even if it wouldn't work for apps using CSS Modules that don't leave part of the original class name.
Option 1 seems like the more proper way with modules. I do like option 2 because that can allow you to match multiple classes and seems more robust.
I'll also introduce option 3:
is('[class*="has-Error--"]', '#idThatWouldHaveError')
I think the artifact for this ticket is we update the docs for usage with CSS guides. We can use option 1 today I believe and option 3 works for sure.
When you import styles into a js file its basically an object with the real class name as the key & the value is the CSS module class name.
// ...
import styles from 'styles.css';
@page class MyPage {
// styles --> { hasError: 'hasError--hbQY8' }
thingHasError = hasClass(styles.hasError)
}
(moved from thefrontside/bigtest#52)
https://github.com/bigtestjs/interactor/blob/master/src/interactor.js#L277
Interactor applies text
, value
, isVisible
, isHidden
, and isPresent
as default properties.
While working with interaction page objects, I'm seeing stuff similar to this a lot:
hasField = isPresent('input[data-test-field]');
focusField = focusable('input[data-test-field]');
fillField = fillable('input[data-test-field]');
blurField = blurable('input[data-test-field]');
What if we simplified that with a single property helper?
field = input('input[data-test-field]');
That has a predetermined set of properties...
page
.field.focus()
.field.fill('value')
.field.blur()
We could do something similar with other properties as well.
error = element('[data-test-error]');
...
expect(page.error.exists).to.be.true
expect(page.error.text).to.equal('some error')
And maybe even a way to compose these common properties?
field = element('[data-some-thing]').focusable().blurable().fillable()
(moved from thefrontside/bigtest#80)
It would be nice to have a way to check every member of a collection against a predicate that returns the results &&
ed together.
Given a collection such:
items = collection($selector, {
isSelected: hasClass('selected', $child)
});
The ability to add something like the following property would be boss:
allItemsSelected = all(this.items(), item => item.isSelected);
(moved from thefrontside/bigtest#65)
This would work with <select>
elements by selecting the option containing the text.
Currently, we can use fill
/fillable
to set the value of a <select>
element. However, in practice we typically select an option based on it's text value.
The fill
/fillable
method does not fail when the value is not present in the list of options, so this can lead to some confusing failed tests. The select
/selectable
method should fail when it cannot find the option with the specified text.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.