Можно ли написать метод isAlertDisplayed в отдельном файле AlertHelper?

Я пытаюсь написать метод isAlertDisplayed в отдельном файле AlertHelper, используя Playwright TypeScript. Мой тестовый сценарий: при нажатии кнопки в течение 5 секунд предупреждение не появляется.

Это тест «При нажатии кнопки оповещение появится через 5 секунд» по ссылке . при нажатии кнопки предупреждение не появляется в течение 5 секунд. Я хочу убедиться в этом:

  • оповещения нет на четвертой секунде
  • предупреждение появляется после пятой секунды. Я не смог найти подходящих примеров в Интернете. и спросил даже

Параметр моей страницы передается через экземпляр PageManager, а экземпляры объекта страницы создаются и возвращаются объектом PageManager pm.

Вот как я вызываю свой метод:

// Verifying alert is not displayed after 4 seconds
const isAlertPresent1 = await pm.AlertHelper().isAlertDisplayed(4000);
expect(isAlertPresent1).toBe(false);

// Verifying alert is displayed after waiting for another 2 seconds
const isAlertPresent2 = await pm.AlertHelper().isAlertDisplayed(2000,true);
expect(isAlertPresent2).toBe(true);

А метод ChatGPT, который не работает, выглядит следующим образом:

async isAlertDisplayed(timeout: number = 1000, dismissAlert: boolean = true): Promise<boolean> {
    try {
        // Add an event listener for the dialog event
        const alertPromise = new Promise<boolean>(resolve => {
            this.page.once('dialog', async dialog => {
                if (dismissAlert) {
                    await dialog.dismiss(); // Dismiss the alert to allow further actions if needed
                }
                resolve(true);
            });
        });

        // Wait for the specified timeout period
        await new Promise(resolve => setTimeout(resolve, timeout));

        // Check if the alert was displayed during the timeout period
        return await Promise.race([alertPromise, Promise.resolve(false)]);
    } catch (error) {
        console.error('Error checking for alert:', error);
        return false;
    }
}

Есть идеи, как реализовать такой метод? Это очень простая функция Browse.isAlertOpen() в WebdriverIO, но ее очень сложно написать в Playwright. Не удалось найти пример кода или методов в Интернете.

@ggorlen это тест «При нажатии кнопки оповещение появится через 5 секунд» по ссылке . при нажатии кнопки предупреждение не появляется в течение 5 секунд. Я хочу проверить следующее: - оповещения нет на четвертой секунде - оповещения нет после пятой секунды. Я не смог найти подходящих примеров в Интернете. и спросил даже ChatGPT, но общее решение тоже не работает.

Ceyhun Ganioğlu 11.06.2024 23:38

Хорошо, хорошее начало, но как мне использовать isAlertDisplayed? Мне нужен весь ваш код, чтобы я мог запустить сайт и набор тестов и реально помочь. Пожалуйста, найдите время и прочтите ссылку минимального воспроизводимого примера — «Предоставьте все части, которые нужны кому-то другому для воспроизведения вашей проблемы, в самом вопросе».

ggorlen 12.06.2024 01:59

сама проблема в том, что этот метод не работает. если вам нравится воспроизводить, просто вызовите это из метода драматурга. перейдите на страницу, нажмите эту кнопку и вызовите метод, как я. больше ничего не нужно.

Ceyhun Ganioğlu 13.06.2024 02:05

Хорошо, достаточно близко, я могу с этим поработать. Спасибо. Я вижу страницу demoqa.com/alerts, которую можно воспроизвести — я отвечу, когда у меня будет время.

ggorlen 13.06.2024 02:13
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
4
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение состоит в том, чтобы удалить прослушиватель, если тайм-аут происходит до диалога:

import {expect, test} from "@playwright/test"; // ^1.42.1

const waitForDialog = async (page, timeout): Promise<boolean> => {
  return new Promise((resolve, reject) => {
    const handleDialog = async dialog => {
      await dialog.dismiss();
      resolve(true);
    };
    page.once("dialog", handleDialog);
    setTimeout(() => {
      page.off("dialog", handleDialog);
      resolve(false);
    }, timeout);
  });
};

test("clicking button shows alert after 5 seconds", async ({page}) => {
  test.setTimeout(10_000)
  const url = "https://demoqa.com/alerts";
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const dialogPromise = waitForDialog(page, 4000);
  await page.locator("#timerAlertButton").click();
  expect(await dialogPromise).toBe(false);
  expect(await waitForDialog(page, 2000)).toBe(true);
});

Закомментируйте page.off, чтобы воспроизвести ошибку.

Вы можете изменить это, чтобы это был одиночный вызов, например waitForDialog(page, {begin: 4000, end: 6000}): выбросить или отклонить с помощью false, если предупреждение сработает до begin, а также если end превышено. И/или сделайте его собственным сопоставителем.

Обратите внимание: поскольку время веб-страницы — вещь непостоянная, возможно, вам захочется предоставить диалогу немного больше свободы, чем 2 секунды.

Возможно, когда-нибудь в Playwright появится обработчик диалогов на основе обещаний, например waitForDialog. Тогда будет легче это сделать.

Тесты проходят, когда я копирую ваш код. А нельзя ли посмотреть, точно проверить на глаз, что происходит? Я попытался запустить тест драматурга npx --ui, но он ничего не показывает о том, что предупреждение появляется на странице через 6 секунд. другое дело, я не понимаю, почему waitForDialog присваивается переменной и пишется до клика. Я предпочитаю в своих фреймворках и тестах подход «одна строка для одного шага/проверки», насколько это возможно. Драматург очень странен в этом плане.

Ceyhun Ganioğlu 18.06.2024 01:02

Вы можете попробовать замедлить ход событий или действовать поэтапно. Playwright работает быстро, и я не уверен, как он отображает диалоги в тестовом пользовательском интерфейсе. Если вы сначала нажмете кнопку мыши, прежде чем дождаться диалогового окна, вы пропустите его появление. Событие срабатывает при первом появлении диалогового окна — оно не проверяет, существует ли уже существующее диалоговое окно. В этом случае предполагается, что диалоговое окно запустится позже, но мы хотим избежать ложного срабатывания, когда диалоговое окно появляется мгновенно, что является распространенным случаем, когда диалоговые окна появляются после щелчка.

ggorlen 18.06.2024 01:12

Утверждение диалогов — довольно редкая вещь, особенно диалоги с задержкой, поэтому я не вижу большой проблемы в том, что «Драматург» не подходит для этого конкретного случая. Большинство современных сайтов вообще не используют диалоги.

ggorlen 18.06.2024 01:15

Очередная месть ДВ. Ответ работает отлично.

ggorlen 30.06.2024 17:11

Имеет смысл. Спасибо. :)

Ceyhun Ganioğlu 01.07.2024 20:07

Другие вопросы по теме