-
Notifications
You must be signed in to change notification settings - Fork 90
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
Chaining from the root #433
Comments
@ro0gr for this one const form = create({
firstName: { scope: '#firstName' },
lastName: { scope: '#lastName' },
submit: clickable('button')
});
await form.firstName.fillIn('John')
await form.lastName.fillIn('Doe')
await form.submit(); Have you evaluated the possibility of using the await form
.firstName.as(input => input.fillIn('John'))
.lastName.as(input => input.fillIn('Doe'))
.submit(); I'm not sure if http://ember-cli-page-object.js.org/docs/v1.15.x/api/as What do you think? |
@san650 it's interesting. I haven't considered it until have read your comment. I'm pretty sure the I don't see a reason why it wouldn't work. However, I find the As far as I can see, the purpose of the myPage.header.searchBar.as((s) => {
assert.ok(s.isVisible);
assert.equal(s.text, 'something');
}) However, once you need to perform another set of operations on the same nested component, you have to repeatl the whole path to the component again: myPage.header.searchBar.as((s) => {
// another set of operations on the filter...
}) From the other side, I find it a useful pattern to simply have short-hands for the nested components which I frequently use in a specific test module: // Make a shorthand once, at the very top of the test module
const { searchBar } = myPage.header; The assert.ok(searchBar.isVisible);
assert.equal(searchBar.text, 'something'); In other words, I believe, a simple JS assignment completelly solves the So I think in the current form of |
I think that the proposed form of the const username = form.username.fork();
const lastname = form.lastname.fork(); I think rather than forking the current node, we should fork all the immediate children. That would allow us to perform shorthands destruction in one line: const { username, lastname } = form.forkChildren(); // oh, this long, terrible name and we can still do a regular assignment, if it's sufficient: const username = form.forkChildren().username; |
Updated description with the |
Problem
In the guides we currently have definitions like:
which are used in the following way:
The problem with the definition is that once we need some additional functionality, like getting a value of input or additional actions, we have to duplicate selectors and expand definition with new properties names which may be hard to follow when you write a test:
A better approach would be to use nested components for that:
However we are not able to use chaining anymore, cause after an action is invoked we are only permitted to continue chaining on the object where the action was called/defined. So the test has to be re-written in the following way:
Proposal
I'd like to be able to have a chaining support when I use nested components, so I can write a test like:
In order to make it possible actions should change behavior from returning a current node to returning a page object
root
as a context for the following chain.Note: A page object root is a node on which
create
was called:I'm not sure yet how much does it take to implement, but I'm pretty confident it should noticably simplify some of internals.
Drawbacks
The main drawback is that it doesn't seem possible to make it in a backward compatible way. We can try to add a codemod transform to ease the transition. However, in my opinion, the change should not be included in v1.
The other drawback is that in some cases it may be unclear that we have a
root
at all:In this is case it feels natural to expect that
blur
would perform on ausername
page object.However it would be called on the root
form
page object.Additionally sometimes I assume someone really wants to keep chaining on a specific level of nesting(change the root). For such cases I can think of an additional API to
fork
a page object with the newroot
but preserving parent scopes:Alternatives
Expose root property
A way to provide more control over a chainable node can be to expose a
root
property for each page object:I find it a bit clumsy, but it can be added in a backward compatible way.
Do nothing
If we do nothing, then we don't have a way to use chaining with a full power. Currently we don't have a way to access parent attributes once we've interacted with a nested component which is quite limiting.
The text was updated successfully, but these errors were encountered: