Dusk: Using `type` or `keys` sometimes does not finish

Created on 5 May 2017  Â·  19Comments  Â·  Source: laravel/dusk

I've been trying to work around this issue but nothing seems to consistently work. I've tried both type('selector', 'text') as well as keys('selector', 'text') but sometimes it just doesn't finish typing everything. There is no consistency here, sometimes it works, sometimes it doesn't. I even tried to do a pause(1000) after type'ing or keys'ing. I feel like this is a fundamental issue unless someone here has any idea what's going on.

Test Code (this one is specifically a Bootstrap modal, but regular forms have issues too)

public function copyExisting(Browser $oBrowser, $sCopyName, $sJobNumber = '8675309') {
  $oBrowser->waitFor('input[name=newName]')
    ->type('input[name=newName]', $sCopyName)
    ->type('input[name=newJobNumber]', $sJobNumber)
    ->press('DONE');
}

Have you tried to reproduce on a clean install?

  • Tested on clean install

    Have you tried to isolate the elements that causes the issue?

  • There is no isolation needed here. I've isolated on every possible thing and can reproduce it sporadically.

    Have you tested with different elements?

  • Tested with different elements, both newName and newJobNumber above.

    Have you tested with different pages?

  • Have tested it with different pages.

    What OS are you running it on?

  • Running this on a vagrant box (boxcutter/ubuntu1604) within macOS (10.12.4 - Sierra).

    Are you using GUI (Graphic User Interface)? Can you actually see the browser?

  • Yes, using GUI. Can see the browser and see it failing to finish typing.

    How do you detect the problem? Do you see half the text in the screenshot?

  • Both screenshot and GUI.

    What error messages do you have?

  • Error message comes when I try and look for the element because it can't find it due to text not matching.

Most helpful comment

Same bug here:

$this->browse(function (Browser $browser) {
    $headline = $this->generateHeadline('head1');

    $browser->visit(new PlainPage())
        ->toSomePlainPageActions()
        ->whenAvailable('@block_modal', function ($modal) use($headline) {
            $modal->select('tag', 'h3')
                ->type('title',$headline) //<---- HERE IS THE PROBLEM
                ->press('Save changes');
        }) ->waitUntilMissing('@block_modal')
        ->assertSee($headline);
});

$headline is e.g string(46) Voluptas ad ab assumenda cupiditate. and type only insert string(2) Vo

my fix or (%#$#) workaround is to go across value so

$modal->select('tag', 'h3')
    ->value('input[name=title]',$headline) //<---- FIXES THE PROBLEM
    ->press('Save changes');

I dont have debugged this deeper but the problem is is in the driver sendKeys function. keys and type use this function, so switch between them will not help.

All 19 comments

You haven't given much information for us to help you.

  • Share your testing code;
  • Try to reproduce on a clean install;
  • Try to isolate the element that causes the issue
  • Test with different elements
  • Test with different pages
  • What OS are you running it on?
  • Are you using GUI (Graphic User Interface)? Can you actually see the browser?
  • How do you detect the problem? Do you see half the text in the screenshot?
  • What error messages do you have?

Initial comment updated.

If that testing function is being given to $this->browser in the DuskTestCase context, then you're receiving 3 different browsers as parameters and then you're passing a Browser instance instead of a text.

It might seem hard to understand this, but just stop using parameter variables and use static text.

public function copyExisting(Browser $oBrowser) {
  $oBrowser->waitFor('input[name=newName]')
    ->type('input[name=newName]', 'abc')
    ->type('input[name=newJobNumber]', '123')
    ->press('DONE');
}

Oh really? That really messes with making functions extensible. So how is my copyExisting function receiving the correct text? It's not like this is failing completely, I actually just ran it headlessly and it worked.

I'm having the same problem, only after upgrading to Laravel 5.5 and Dusk 2.0 (although it might be just coincidence, but my same tests never seemed to fail in this way before).

@SpellChucker did you ever solve it? It's driving me crazy. Thanks.

Ahh, although this surprised me, I can understand if Laravel maintainers will say that this is not a bug (though I'm not sure, because it's not the behavior I expected).

My tests seem to be working after changing from:

    $browser->visit(self::PATH)
            ->clickLink(self::LINK)
            ->waitFor(self::HIDDEN_FORM, 1)// Wait a maximum of one second for the selector...                    
            ->type(self::NAME_FIELD, self::NAME_VALUE)
            ->type(self::EMAIL_FIELD, '[email protected]')
            ->click(self::SIGNUP_BUTTON)
            ->waitForLocation(self::FORM_ACTION, 1)
            ->assertPathIs(self::FORM_ACTION);

to:

    $browser->visit(self::PATH)
            ->clickLink(self::LINK)
            ->waitFor(self::HIDDEN_FORM, 1)// Wait a maximum of one second for the selector...                    
            ->type(self::NAME_FIELD, self::NAME_VALUE)
            ->type(self::EMAIL_FIELD, '[email protected]');
    $browser->click(self::SIGNUP_BUTTON)
            ->waitForLocation(self::FORM_ACTION, 1)
            ->assertPathIs(self::FORM_ACTION);

I broke the chain into 2 commands.

I'm having the same problem

laravel/dusk 2.0
laravel 5.5

The solution proposed by @ryancwalsh doesn’t work for me

My workaround was to take a screenshot before button click



->type(‘field’,’some text’)
->screenShot(“aShot”)
->press("button[id='resourceSaveButton']")



Same bug here:

$this->browse(function (Browser $browser) {
    $headline = $this->generateHeadline('head1');

    $browser->visit(new PlainPage())
        ->toSomePlainPageActions()
        ->whenAvailable('@block_modal', function ($modal) use($headline) {
            $modal->select('tag', 'h3')
                ->type('title',$headline) //<---- HERE IS THE PROBLEM
                ->press('Save changes');
        }) ->waitUntilMissing('@block_modal')
        ->assertSee($headline);
});

$headline is e.g string(46) Voluptas ad ab assumenda cupiditate. and type only insert string(2) Vo

my fix or (%#$#) workaround is to go across value so

$modal->select('tag', 'h3')
    ->value('input[name=title]',$headline) //<---- FIXES THE PROBLEM
    ->press('Save changes');

I dont have debugged this deeper but the problem is is in the driver sendKeys function. keys and type use this function, so switch between them will not help.

Closing this issue because it's already solved, old or not relevant anymore. Feel free to reply if you're still experiencing this issue.

@driesvints
This is not solved, I'm currently fighting with exactly the same issue. Automatically closing every old issue is a very poor way to maintain a project.

For me it just hangs when typing into a password field.

@MightyPork Please provide a reproducible example. What versions of Dusk and Chrome are you using?

here's my dusk section in composer.lock, it's for Laravel 5.6. Chrome driver is the default it came with.
I'm not sure if it uses my system chrome, or how it works? The installed google-chrome-stable is 67.0.3396.99.

I've verified that replacing type() with value() works fine, so probably just changing type() to internally call value() would be a solution.

{
            "name": "laravel/dusk",
            "version": "v2.0.14",
            "source": {
                "type": "git",
                "url": "https://github.com/laravel/dusk.git",
                "reference": "a7aedd50dd5b4965ee589087ba575cb03981fe80"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/laravel/dusk/zipball/a7aedd50dd5b4965ee589087ba575cb03981fe80",
                "reference": "a7aedd50dd5b4965ee589087ba575cb03981fe80",
                "shasum": ""
            },

What's the result of vendor/laravel/dusk/bin/chromedriver-linux --v (assuming you are running Linux)?

$ ./vendor/laravel/dusk/bin/chromedriver-linux --v
ChromeDriver 2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881)

Please upgrade your Chrome browser and ChromeDriver to the latest versions. You can download the ChromeDriver here or use my package.

updated to ChromeDriver 2.45.615279 (12b89733300bd268cff3b78fc76cb8f3a7cc44e5) and chrome 71. Didn't help in the slightest, it still hangs.
example test:

public function testGuestRedirectedToIntendedPageAfterLogin()
{
    $user = $this->newUser();
    $user->password = bcrypt("hunter2");
    $user->admin = true;
    $user->save();

    $this->browse(function (Browser $browser) use ($user) {
        $browser->logout(); // ensure we're not logged in

        $browser->visit('/setup');
        $browser->on(new LoginPage)
            ->value('@name', $user->name) // <- if you put 'type' here, it hangs
            ->value('@password', "hunter2") // <-
            ->click('@submit');

        $browser->assertPathIs('/setup');
        $browser->assertAuthenticatedAs($user);
    });
}

the test reliably does not finish when type() is used. I checked by putting echo after each operation and really tracked it down to the use of type()

Does your site use JavaScript to interact with the inputs (e.g. for validation)?

@staudenmeir no, nothing for these particular inputs. I think there must be something broken in the ChromeDriver. anyway, I worked around like this:

class MyBrowser extends Browser
{
    /**
     * Work-around for the vendor-provided type() method being too slow
     * and often freezing.
     *
     * @param string $selector
     * @param string $text
     * @return $this|Browser
     */
    public function type($selector, $text)
    {
        \Log::debug("[browser] Type \"$text\" -> $selector");

        $this->ensurejQueryIsAvailable();
        $selector = $this->resolver->format($selector);
        $this->driver->executeScript(
            "
            $('{$selector}').val(".json_encode($text).").trigger('change');
            "
        );
        return $this;
    }
}

and changed DuskTestCase to return this instance instead of the original one. Works a treat

    /**
     * Create a new Browser instance.
     *
     * @param  \Facebook\WebDriver\Remote\RemoteWebDriver  $driver
     * @return \Laravel\Dusk\Browser
     */
    protected function newBrowser($driver)
    {
        // create a custom browser with fixes and convenience methods
        $browser = new MyBrowser($driver);
        $browser->resize(1280, 768); // adjust size if desired
        return $browser;
    }

I had same problem as @MightyPork and it was caused by FreshChat (https://developers.freshchat.com) customer service chat plugin, if I comment it out from layout, type works, if it is included type doesn't work. Maybe some other third party plugins can cause same effect.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pdbreen picture pdbreen  Â·  4Comments

marcusmoore picture marcusmoore  Â·  3Comments

rauldeheer picture rauldeheer  Â·  4Comments

ahtinurme picture ahtinurme  Â·  6Comments

bruno-barros picture bruno-barros  Â·  6Comments