Я пытаюсь написать метод 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. Не удалось найти пример кода или методов в Интернете.
Хорошо, хорошее начало, но как мне использовать isAlertDisplayed? Мне нужен весь ваш код, чтобы я мог запустить сайт и набор тестов и реально помочь. Пожалуйста, найдите время и прочтите ссылку минимального воспроизводимого примера — «Предоставьте все части, которые нужны кому-то другому для воспроизведения вашей проблемы, в самом вопросе».
сама проблема в том, что этот метод не работает. если вам нравится воспроизводить, просто вызовите это из метода драматурга. перейдите на страницу, нажмите эту кнопку и вызовите метод, как я. больше ничего не нужно.
Хорошо, достаточно близко, я могу с этим поработать. Спасибо. Я вижу страницу demoqa.com/alerts, которую можно воспроизвести — я отвечу, когда у меня будет время.






Решение состоит в том, чтобы удалить прослушиватель, если тайм-аут происходит до диалога:
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 присваивается переменной и пишется до клика. Я предпочитаю в своих фреймворках и тестах подход «одна строка для одного шага/проверки», насколько это возможно. Драматург очень странен в этом плане.
Вы можете попробовать замедлить ход событий или действовать поэтапно. Playwright работает быстро, и я не уверен, как он отображает диалоги в тестовом пользовательском интерфейсе. Если вы сначала нажмете кнопку мыши, прежде чем дождаться диалогового окна, вы пропустите его появление. Событие срабатывает при первом появлении диалогового окна — оно не проверяет, существует ли уже существующее диалоговое окно. В этом случае предполагается, что диалоговое окно запустится позже, но мы хотим избежать ложного срабатывания, когда диалоговое окно появляется мгновенно, что является распространенным случаем, когда диалоговые окна появляются после щелчка.
Утверждение диалогов — довольно редкая вещь, особенно диалоги с задержкой, поэтому я не вижу большой проблемы в том, что «Драматург» не подходит для этого конкретного случая. Большинство современных сайтов вообще не используют диалоги.
Очередная месть ДВ. Ответ работает отлично.
Имеет смысл. Спасибо. :)
@ggorlen это тест «При нажатии кнопки оповещение появится через 5 секунд» по ссылке . при нажатии кнопки предупреждение не появляется в течение 5 секунд. Я хочу проверить следующее: - оповещения нет на четвертой секунде - оповещения нет после пятой секунды. Я не смог найти подходящих примеров в Интернете. и спросил даже ChatGPT, но общее решение тоже не работает.