Search code examples
testingautomationautomated-testspopupplaywright

How to deal with popups in Playwright?


I want to delete an article, on the normal site I usually click on the Delete button and then I see the popup in which I have to confirm my choice.

So, here is my code

const {test, expect} = require('@playwright/test');
const { createNewArticle, generateRandomUser, generateRandomArticle } = require('../../helpers');

test.only('should delete an article after clicking on [Delete Article]', async ({page}) => {
  const user = generateRandomUser();
  const article = generateRandomArticle();

  const r = await createNewArticle(user, article);

  const slug = r.data.article.slug;

  const {email, password} = user;

  await page.goto('https://conduit.mate.academy/user/login');

  // await page.pause();

  await page.getByPlaceholder('Email').fill(email);
  await page.getByPlaceholder('Password').fill(password);
  await page.getByRole('button', { name: 'Sign in' }).click();

  await page.waitForURL('https://conduit.mate.academy/')

  await page.goto(`https://conduit.mate.academy/article/${slug}`);

  await page.locator('.btn.btn-outline-danger.btn-sm').first().click();

  await page.goto(`https://conduit.mate.academy/profile/${user.username}`);

  await expect(page.locator('.article-preview')).toHaveCount(1);
  await expect(page.locator('.article-preview')).toHaveText('No articles are here... yet.');
})

Here is the reason it fails error So, on this site if there is no articles then this caption is shown No articles are here... yet." But for some reason it found the article that should have been deleted.

When I look into trace, then I see this trace So, it finds elements it clicks on it, but it just wasn't deleted.

I assume that this can be because of the popup, when I'm on the site I should confirm with popup that I want to delete the article, but when I'm in Playwright I didn't see it, I read that Playwright didn't handle them by default, so I tried to start with basic of working with popups and added this line of code

const popup = await page.waitForEvent('popup');

After that I got this error error So, can someone please point out what can be the reason?

I thought only about popups, so I went to the documentation, chatGPT, youtube videos and tried to use some codes like this one

const popup = await page.waitForEvent('popup');

await popup.waitForFunction(() => {
  const buttons = document.querySelectorAll('button');
  for (const button of buttons) {
    if (button.innerText === 'OK') {
      button.click();
      return true;
    }
  }
  return false;
});

But anyway it just timed out because it was waiting for this popup and it didn't appear.


Solution

  • Don´t await waitForEvent before you click delete, that way your code wont continue executing before the delete button is pressed. I modified your code with one way to solve it with page.on('dialog'), not popup:

    const { test, expect } = require('@playwright/test');
    const { createNewArticle, generateRandomUser, generateRandomArticle } = require('../../helpers');
    
    test.only('should delete an article after clicking on [Delete Article]', async ({ page }) => {
        const user = generateRandomUser();
        const article = generateRandomArticle();
    
        const r = await createNewArticle(user, article);
    
        const slug = r.data.article.slug;
    
        const { email, password } = user;
    
        await page.goto('https://conduit.mate.academy/user/login');
    
        await page.getByPlaceholder('Email').fill(email);
        await page.getByPlaceholder('Password').fill(password);
        await page.getByRole('button', { name: 'Sign in' }).click();
    
        await page.waitForURL('https://conduit.mate.academy/')
        
        await page.goto(`https://conduit.mate.academy/article/${slug}`);
        
        // 1. Initiate event listener
        page.on('dialog', async dialog => {
            // 3. Do stuff with the dialog here (reject/accept etc.)
            console.log(dialog.message());
            await dialog.accept()
        });
        // 2. Press the delete button
        await page.locator('.btn.btn-outline-danger.btn-sm').first().click();
    
        // 4. Execution continues:
        await page.goto(`https://conduit.mate.academy/profile/${user.username}`);
    
        await expect(page.locator('.article-preview')).toHaveCount(1);
        await expect(page.locator('.article-preview')).toHaveText('No articles are here... yet.');
    })