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

introduce intention revealing UI element specific helper functions #19

Open
cer opened this issue Jun 2, 2021 · 4 comments
Open

introduce intention revealing UI element specific helper functions #19

cer opened this issue Jun 2, 2021 · 4 comments
Assignees

Comments

@cer
Copy link
Contributor

cer commented Jun 2, 2021

The page object functions are written in terms of low level functions.

It would be better to introduce some helper functions.

This is a repeated pattern:

    await waitClickAndType(page, SEL.FORM_FIELD_ADDRESS, testData.address);
    await waitForTimeout(page, 10);

could be replaced by

    textField(page, SEL.FORM_FIELD_ADDRESS).enter(testData.address)
  • Removes duplication
  • Makes it clear what is happening
@cer
Copy link
Contributor Author

cer commented Jun 2, 2021

Actually, I realized that when writing #21 (comment) that this can be improved further:

Instead of

    await   textField(page, SEL.FORM_FIELD_ADDRESS).enter(testData.address);

it could be better to have

   await addressField(page).enter(testData.address);

where addressField() is written in terms of textField()

@cer
Copy link
Contributor Author

cer commented Jun 2, 2021

So in other words there is a hierarchy:

  • Test
  • Page Object, e.g. landingPage
  • Page component, e.g. addressField
  • UI element, textField()

@dartandrevinsky
Copy link
Collaborator

This next-to-last-step of hierarchy (Page component, e.g. addressField) seems a nice thing to have but once it comes to implementation it starts backfiring. Namely, the desired pattern to be so:

await addressField(page).enter(testData.address);

but it is not clear at all what this part should do:

addressField(page)

? Accumulate the arguments? always require a second method, like enter(data) : Promise<*>? What if we need only to locate (ensure presence) an input?

But the point is that awaiting each link in a chained call looks very cumbersome and it is so easy to introduce a mistake.

Actually, the puppeteer's API already has nearly identical methods and they have all be await-ed, as the queue is called. Like so:

await (await addressField(page)).enter(testData.address);

I'll have to think over it before implementing it.

Maybe something like this?

await forAddressField(page, [
  f => f.enter(text) // is awaited from the implementation
]);

Thoughts?

@cer
Copy link
Contributor Author

cer commented Jun 28, 2021

await (await addressField(page)).enter(testData.address);

Yes. This is ugly

but it is not clear at all what this part should do:

addressField(page)

? Accumulate the arguments? always require a second method, like enter(data) : Promise<*>?

Sounds like addressField(page) would need to return an object that has an enter() method, which returns a Promise.

What if we need only to locate (ensure presence) an input?

Sounds like in addition to enter() the object would have another method for verifying existence, which returns a future.

dartandrevinsky added a commit that referenced this issue Jun 28, 2021
dartandrevinsky added a commit that referenced this issue Jun 29, 2021
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

No branches or pull requests

2 participants