Я пытаюсь нажать кнопку «Отправить» с помощью Playwright, но не могу заставить это работать. У меня есть следующий HTML-код.
<table>
<tr>
<td id = "ct100" onscroll = "scollPosition(this);">
<!-- some html form -->
<input value = "Save" type = "submit" class = "btn" />
</td>
<td id = "ct101" onscroll = "scollPosition(this);">
<input type = "text" id = "input_01" onchange = "updateValue();" />
<!-- form input -->
</td>
</table>
Код драматурга:
async saveSetupPage(): Promise<void> {
// If I try to click submit button before any filling up any input, click is working
await page.locator("#input_01").click();
await page.locator("#input_01").fill("some value");
// trying to fill 10-12 input with same above code
// now trying to click on submit button
await page.locator("//*[@id='ct100_btn']").click();
});
Теперь у меня следующая ошибка:
locator.click: Timeout 30000ms exceeded.
Call log:
- waiting for locator('//*[@id = "ct100_btn"]')
- locator resolved to <input value = "Save" type = "submit" class = "btn" id = "../>
- attempting click action
- waiting for element to be visible, enable and stable
- scrolling into view if needed
- done scrolling
- <div class = "UpdateProgress">
Спасибо большое за помощь, моя проблема пока не решена. Судя по вашему предложению, похоже, проблема не в кнопке сохранения. Существует много js-кода, который может быть проблемой.
как @ggorlen
сказал, что ваш локатор кажется неправильным ("//*[@id='ct100_btn']"), поскольку в вашем фрагменте HTML такого элемента нет.
Вместо этого используйте более точный локатор, основанный на доступных атрибутах, таких как класс или значение. а также убедитесь, что драматург ждет, пока элементы станут видимыми, включенными и стабильными, прежде чем взаимодействовать с ними, например, для вашего Playwrite code
async saveSetupPage(): Promise<void> {
await page.locator("#input_01").fill("some value");
await page.waitForTimeout(1000);
await page.locator("input[type='submit'][value='Save']").click();
await page.waitForNavigation();
}
waitForTimeout()
не рекомендуется. Вы должны использовать его только для отладки. .click()
имеет автоматическое ожидание, поэтому waitForTimeout()
не требуется. waitForNavigation()
устарел и заменен на waitForUrl()
, но я не понимаю, с какой целью вы это предлагаете.
Спасибо за ваш отзыв! Я понимаю, что использование `waitForTimeout()` обычно не рекомендуется, но я чувствовал, что элементы формы приложения и их взаимодействия, такие как onscroll
и onchange
, могут вызвать дополнительную динамическую загрузку или обновление контента, а использование waitForTimeout()
гарантирует, что все эти динамические изменения будут завершены раньше переходим к следующим действиям, поскольку это обеспечивает буферный период для обработки любых непредвиденных задержек при рендеринге или выполнении JavaScript. Еще раз спасибо за полезный совет, я прочитаю об этом больше и попробую в дальнейшем.
Спасибо большое за помощь, моя проблема пока не решена. Я пытаюсь это понять.
@GifftyCode waitForTImeout
для этого использовать не следует. Используйте waitForFunction
, waitForResponse
или waitForSelector
, чтобы дождаться конкретных изменений. В любом случае, ОП никогда не делился страницей, так откуда вы знаете, что есть динамические загрузки? waitForNavigation
устарел и находится не в том месте, поэтому это вызывает состояние гонки, которое может привести к зависанию скрипта. Его необходимо установить до действия, вызывающего навигацию, а не после.
@sabbir Подумайте о том, чтобы поделиться минимально воспроизводимым примером по запросу, чтобы людям не приходилось угадывать ваш вариант использования. Что именно еще не решено?
Вот как вы можете решить проблему, нажав кнопку «Отправить» с помощью Playwright в вашем конкретном сценарии:
Проблема
Время действия действия locator.click истекает, поскольку Playwright не может найти кнопку отправки с указанным селектором (//*[@id='ct100_btn']). В предоставленном HTML-коде нет элемента с идентификатором ct100_btn.
Решение
Обновите селектор, чтобы правильно нацелить кнопку отправки на основе предоставленного вами HTML.
HTML
<table>
<tr>
<td id = "ct100" onscroll = "scollPosition(this);">
<!-- some html form -->
<input value = "Save" type = "submit" class = "btn" />
</td>
<td id = "ct101" onscroll = "scollPosition(this);">
<input type = "text" id = "input_01" onchange = "updateValue();" />
<!-- form input -->
</td>
</tr>
</table>
Кодекс драматурга
async saveSetupPage(): Promise<void> {
// Fill the input field
await page.locator("#input_01").fill("some value");
// Click the submit button
await page.locator('td#ct100 input[type = "submit"]').click();
}
У меня была аналогичная проблема раньше. Моя проблема заключалась в том, что когда я заполнял ввод, какой-то клиентский валидатор давал сбой, поэтому кнопка отправки была отключена.
Попробуйте проверить, не удалась ли какая-либо проверка на стороне сервера/клиента или нет, и кнопка отправки отключена или нет.
Надеюсь, это будет полезно.
ct100_btn
нет в вашем HTML. Попробуйте"#ct100 .btn"
. Но если исправление не помогло, поделитесь дополнительной информацией о странице, чтобы воспроизвести проблему. Это может быть оверлей, iframe, блок Cloudflare, произвольное поведение или время JS или некоторый дополнительный контекст, который необходимо предоставить для объяснения сбоя. См. минимальный воспроизводимый пример.