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

Assertion inside page object #2

Closed
gquemener opened this issue Apr 2, 2013 · 5 comments
Closed

Assertion inside page object #2

gquemener opened this issue Apr 2, 2013 · 5 comments

Comments

@gquemener
Copy link
Contributor

Hello,

I'd like to take advantage of the WebAssert class methods (https://github.com/Behat/Mink/blob/develop/src/Behat/Mink/WebAssert.php) inside a page object.

For example, I have a step "I should see item1" defined in a FeatureContext. Then, I could implement it like so:

public function iShouldSeeItem($item)
{
    $this->assertSession()->elementTextContains('css', '.items', $item)
}

But it means declaring page-related information (css selector here), inside my feature context, which is the opposite of what this extension intends to solve ;)

So, what d'you think should be the best option here? Should I just inject the WebAssert in my Page class?

This is kinda trivial question, sorry if it's already been answered (I've read all the doc before).

@gquemener
Copy link
Contributor Author

Oh, I've just seen that it was not even possible to inject the WebAssert class as PageObjectContext extends BehatContext and not MinkContext.

@jakzal
Copy link
Member

jakzal commented Apr 3, 2013

You brought up an interesting issue. In general, assertions don't belong to page objects. I'd say it's good you have difficulties implementing them :)

Page object should provide an interface to your page. When working with page objects, I'd avoid using the assert session when verifying if a text is present on a page. I'd rather ask it the page for details and verify it myself:

if (!$page->findItem($item)) {
    throw new \LogicException(sprintf('Expected to find "%s" item'. $item));
}

It's a bit long. Therefore, I prefer to use the phpspec2-expect helper which brings the phpspec2 matchers to Behat:

expect($page->findItem($item))->notToBe(null);

or:

expect($page->hasItem($item))->toBe(true);

I see nothing wrong with using the assert session, but in this particular case it might defeat the purpose of using page objects.

@jakzal
Copy link
Member

jakzal commented Apr 3, 2013

Actually, the last example could be more readable if I used the Object State Matcher:

expect($page)->toHaveItem($item);

$page->hasItem($item) would be called to verify this expectation.

@gquemener
Copy link
Contributor Author

Why do you think assertion shouldn't be part of the page object? I mean it's just making them smarter to make them know both about page structure and assertion about this structure.

Anyway, don't you think it'd be a good idea to provide two PageObjectContext, one that extends BehatContext (the actual one) and one that extends MinkContext (to have access to the assert session)?

@jakzal
Copy link
Member

jakzal commented Apr 3, 2013

Why do you think assertion shouldn't be part of the page object? I mean it's just making them smarter to make them know both about page structure and assertion about this structure.

This is one of the rules of the page object pattern. Assertions shouldn't be done in the page object. I think it would eventually complicate page objects and make them hard to maintain (why would we need context files?).

By saying we only make assertions in the context files and store knowledge about a page in the page object, we're introducing a clear separation between them.

In other words: page object provides an interface to your page. Verifying (asserting) is another task, which should belong to an other code entity (in our case a context file). Putting both verification and page structure knowledge into one class would effectively make context files redundant. It would be just like when you created one context file per page.

Anyway, don't you think it'd be a good idea to provide two PageObjectContext, one that extends BehatContext (the actual one) and one that extends MinkContext (to have access to the assert session)?

This is done on purpose. Extending MinkContext (or more likely RawMinkContext) would encourage users to call mink in the context files whenever they feel it's easier.

I can imagine situations when you'd want to do it, but it should be occasional. Therefore I don't want it to be the default context. Power users can still implement the PageObjectAwareInterface interface instead of extending the PageObjectContext, so it is still possible to use it with a mink context (but there's effort needed on the user side to do it).

If your main aim is to use the assert session, we're thinking of how to integrate it as a phpspec matcher which could be used with the expect() helper.

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