symfony / panther

A browser testing and web crawling library for PHP and Symfony
MIT License
2.94k stars 222 forks source link

Deal with javascript alert #203

Open pifaace opened 5 years ago

pifaace commented 5 years ago

Hi,

I started to play with panther since 2 days, and I've a little problem with a scenario. I want to delete a article from my app. The process is the following : I press a button, an alert shows up to confirm.

Problem is the WebDriver throws a UnexpectedAlertOpenException ok so I add this to the client $client->getWebDriver()->switchTo()->alert()->accept();

but now I got a NoAlertOpenException: no alert open I'm a little bit lost

here is my test :

public function testDeleteAnArticle()
    {
        $client = static::createPantherClient();

        $crawler = $client->request('GET', '/');

        $crawler = $this->loginAs($client, $crawler, 'admin', 'azerty');

        $crawler = $client->click($crawler->selectLink('Dashboard')->link());
        $crawler = $client->click($crawler->selectLink('ARTICLES')->link());

        $client->getWebDriver()->switchTo()->alert()->accept();

        $crawler = $client->click($crawler->filter('a.is-danger')->eq(5)->link());

        $client->waitFor('.notification');

        $this->assertContains('The article has been successfully deleted', $crawler->filter('.notification')->text());
    }

Someone knows how to deal with this ? Thank you

vladprokopchuk commented 5 years ago

I have the same problem. Cant confirm alert.

emillosanti commented 5 years ago

@pifaace , it appears you've tried to accept the prompt before clicking on delete, maybe try:

$crawler = $client->click($crawler->filter('a.is-danger')->eq(5)->link()); // click on delete
$client->getWebDriver()->switchTo()->alert()->accept(); // accept after clicking on delete
pifaace commented 5 years ago

Hi @emillosanti Yeah I tried this but immediately after this line $crawler = $client->click($crawler->filter('a.is-danger')->eq(5)->link()); // click on delete It throws an Exception UnexpectedAlertOpenException So the second line is ignored

panakh commented 4 years ago

$client->executeScript("document.querySelector('button').click()"); $client->getWebDriver()->switchTo()->alert()->accept();

alexislefebvre commented 4 years ago

I used panakh code:

        $crawler = $this->testClient->request('GET', $path);

        // …

        // Click on “Delete old tweets”
        $testClient->executeScript("document.querySelector('a#tweets-delete').click()");
        $testClient->getWebDriver()->switchTo()->alert()->accept();

        // Pending tweets
        $this->assertStringContainsString(
            '1 pending tweets',
            $crawler->filter('html > body')->text()
        );

I get this error from the line with $crawler:

Facebook\WebDriver\Exception\StaleElementReferenceException : stale element reference: element is not attached to the page document (Session info: headless chrome=80.0.3987.162)

How do we get the $crawler after accepting the alert dialog?

paulb057 commented 4 years ago

Did you work out to get around this? I am having the same problem when I try and go to a new URL or browse away from a page. I am getting the error

Uncaught Facebook\WebDriver\Exception\UnexpectedAlertOpenException: unexpected alert open: {Alert text : }

I am running in PANTHER_NO_HEADLESS mode and i can not see any popup.

try {
    $crawler = $client->request('GET', "https://url.com/newpage.aspx");
} catch (Facebook\WebDriver\Exception\UnexpectedAlertOpenException $e) {
        $client->getWebDriver()->switchTo()->alert()->accept();
} catch (Exception $e) {
}

OR

try {
     $link = $crawler->selectLink('Tasks')->link();
     $client->click($link);
 } catch (Facebook\WebDriver\Exception\UnexpectedAlertOpenException $e) {
         $client->getWebDriver()->switchTo()->alert()->accept();
 } catch (Exception $e) {
 }

And then I get the error

Uncaught Facebook\WebDriver\Exception\NoSuchAlertException: no such alert

Anyone have any ideas on how to get around this?

paulb057 commented 4 years ago

I ended up doing

$client->executeScript("window.onbeforeunload = null");

and the kill the alert code and get me around my problem.

aszenz commented 3 years ago

Same issue, some times the test works, but often times it fails with this exception, note that no alert even appears when using NO_HEADLESS mode so I'm not sure what causes it to fail. Tried all the solution's, nothing works, it's really blocking our usage of panther

simon-chr commented 3 years ago

you need to wait for the alert. this is what I did: $this->chromeClient->wait()->until(WebDriverExpectedCondition::alertIsPresent()); $this->chromeClient->getWebDriver()->switchTo()->alert()->accept();

likeuntomurphy commented 1 year ago

I have a simple link with a data-turbo-confirm attribute. I intermittently experience an UnexpectedAlertOpenException.

My test was using

$client->click($link);
$client->wait()->until(WebDriverExpectedCondition::alertIsPresent());
$client->switchTo()->alert()->accept();

The problem is that with $client->click($link), the Panther client will try to refresh its crawler. This entails another WebDriver request, which may fail, presumably because of timing, if the alert is already present (my understanding is that there can be no interaction with the window at all if the alert is showing.) I’ve seen two different exceptions that are traced back to src/Client.php#L281.

Facebook\WebDriver\Exception\UnknownErrorException: Unexpected server response to findElements command

/app/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:236
/app/vendor/symfony/panther/src/Client.php:281

and

Facebook\WebDriver\Exception\UnexpectedAlertOpenException: unexpected alert open

/app/vendor/php-webdriver/webdriver/lib/Exception/WebDriverException.php:139
/app/vendor/php-webdriver/webdriver/lib/Remote/HttpCommandExecutor.php:385
/app/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:598
/app/vendor/php-webdriver/webdriver/lib/Remote/RemoteWebDriver.php:232
/app/vendor/symfony/panther/src/Client.php:281

I changed my test to the following, and I have not encountered these exceptions at all, even while running the tests dozens of times.

$link->getElement()->click();
$client->wait()->until(WebDriverExpectedCondition::alertIsPresent());

$alert = $client->switchTo()->alert();

// You can make assertions about alert
// $this->assertEquals('Are you sure?', $alert->getText());

$alert->accept();

// My tests don’t require it, but you may need to refresh the crawler manually at this point
// to mirror what `clickLink` does.
// 
// $client->refreshCrawler();