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

fill a form, listen for page-changing events #147

Open
tacman opened this issue Apr 2, 2024 · 10 comments
Open

fill a form, listen for page-changing events #147

tacman opened this issue Apr 2, 2024 · 10 comments

Comments

@tacman
Copy link

tacman commented Apr 2, 2024

First, what a cool library! I was fighting with authenticated users in my tests, still not sure what the problem was, but the actingAs() method works so easily that I'm switching my tests to this.

Two related feature requests. I'd like to be able to fill out a form more easily, and I'd like an event for clicks and submits.

$browser->getForm('registration')
   ->fill(['email' => '[email protected]', 'name' => 'Mr. Ed', 'plainPassword' => 'passw0rd'])
   ->submit()
   ->assert...

Perhaps something like this already exists?

I'd like to create a log that shows the page the test is on, and movement sequence (usually clicked on a link or submitted a form). I used to do that in behat and found it valuable. Start on the homepage (/). Click 'register'. Fill out the form with [...], click "My profile", click "add interests", etc.

But really I just wanted to say how great the tool is, but in order to create an issue I figured I'd add some low-priority wish list item. Thanks again for releasing this, it's so much easier to work with than the regular phpunit client.

@kbond
Copy link
Member

kbond commented Apr 9, 2024

Hey! Thanks for the kind words.

If I understand correctly, what you want should be possible:

$this->browser()
    ->visit('/register')
    ->fillField('email', '[email protected]')
    // ...
    ->click('Submit')
    ->assertOn('/')
    ->assertSuccessful()
    ->assertSee('You have successfully registered')
    ->assertAuthenticated('[email protected]')
;

@tacman
Copy link
Author

tacman commented Apr 9, 2024

Not quite. I want a way to fill a form with a single object rather than repeating fillField.

And ideally a way to fill it by first getting a form, for example if a registration form and login form are on the same page, I'd like to do something like

$this->browser()
    ->visit('/login_or_register_or_forgot_password')
    ->getForm('register')
    ->fillFields(['email' => '[email protected]', 'name' => 'Mr. Ed.', 'plainPassword' => 'AHorseOfCourse'])
    ->submit()
    ->assertOn('/')
    ->assertSuccessful()
    ->assertSee('You have successfully registered')
    ->assertAuthenticated('[email protected]')
;

And somewhere else in the code, I'd like to register a listener for click() and submit(), so that I create a log of my tests, which will end up looking somethink like behat.

Given I am on '/register'
And I submit the 'login' form with
    email: [email protected]
    password: 'abc'
Then I should see "you are logged in"

I realize that behat scenarios are used for creating tests, but they're pretty readable, so I'd like to come up with a way to create my own report like that by listening for click and submit events.

The use case is for creating detailed answers to questions, like "how do I add a new administrator?". The idea is that I would write a test, run it, the listener would create a file in markdown that would then become part of the FAQ.

I know it's a bit of a stretch, I did have this working a few years ago with behat 2, but they changed the implementation in Behat 3

@kbond
Copy link
Member

kbond commented Apr 10, 2024

What about this:

use Symfony\Component\BrowserKit\AbstractBrowser;

$this->browser()
    ->visit('/login_or_register_or_forgot_password')
    ->use(function(AbstractBrowser $client) {
        $client->submitForm('Register', ['email' => '[email protected]', 'name' => 'Mr. Ed.', 'plainPassword' => 'AHorseOfCourse']);
    })
    ->assertOn('/')
    ->assertSuccessful()
    ->assertSee('You have successfully registered')
    ->assertAuthenticated('[email protected]')
;

I want to think a bit more about adding this feature as a native method on Zenstruck\Browser.

@tacman
Copy link
Author

tacman commented Apr 10, 2024

yes, I think that'd work. The sometimes-tricky thing is getting the name/identifier of the form elements, especially checkboxes. I prefer name/id to labels, so that working in a multi-lingual environment is easier.

But this solution looks nice.

What do you think about a click/submit listener?

@kbond
Copy link
Member

kbond commented Apr 10, 2024

The use case is for creating detailed answers to questions, like "how do I add a new administrator?". The idea is that I would write a test, run it, the listener would create a file in markdown that would then become part of the FAQ.

That is a really cool idea. A test drives/validates feature and builds docs.

Just so I understand, you want to use browser to generate files like this (one per test or something)?

Given I am on '/register'
And I submit the 'login' form with
    email: [email protected]
    password: 'abc'
Then I should see "you are logged in"

@tacman
Copy link
Author

tacman commented Apr 10, 2024 via email

@kbond
Copy link
Member

kbond commented Apr 10, 2024

I can see how a some kind of listener can help with generating:

And I submit the 'login' form with
    email: [email protected]
    password: 'abc'

But how would Then I should see "you are logged in" and Given I am on '/register' be generated?

@tacman
Copy link
Author

tacman commented Apr 11, 2024

->assertOn('/')
    ->assertSuccessful()
    ->assertSee('You have successfully registered')

Brainstorming: In each assertX() method, adding this?

this->dispatch(new BrowserEvent(payload: {method: __METHOD__, params: get_env_vars()});

@tacman
Copy link
Author

tacman commented Jun 10, 2024

I want to think a bit more about adding this feature as a native method on Zenstruck\Browser.

Any more thoughts? Maybe mark dispatching an event as experimental until we see how it plays out? Or maybe I can add what I want to the consoleLog and then parse the logs to get what I want for now.

@nikophil
Copy link
Member

this whole idea sounds really cool!

maybe this can be enable like this?

$this->browser()
    ->recordScenario($scenarioName)
    // ... do some recorded stuff
    ->endRecordScenario() // optional

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants