I have an input field, which when hovered over, shows a warning with a text. Now I want to get this warning element, and eventually perform a test like expect(warning_element).to_have_text("Please enter a valid value.")
.
Code to Reproduce :
**app.py : **
from flask import Flask
app = Flask(__name__)
@app.route('/')
def serve_html():
html_content = """
<!DOCTYPE html>
<html>
<head>
<style>
.warning {
display: block;
color: red;
font-size: 14px;
}
</style>
</head>
<body>
<label for="inputField">Text Input:</label>
<input type="text" id="inputField">
<script>
const inputField = document.getElementById('inputField');
let warningMessage;
inputField.addEventListener('mouseover', () => {
if (!warningMessage) {
warningMessage = document.createElement('p');
warningMessage.classList.add('warning');
warningMessage.textContent = 'Please enter a valid value.';
inputField.insertAdjacentElement('afterend', warningMessage);
} else {
warningMessage.style.display = 'block';
}
});
inputField.addEventListener('mouseout', () => {
if (warningMessage) {
warningMessage.style.display = 'none';
warningMessage.remove();
warningMessage = undefined;
}
});
</script>
</body>
</html>
"""
return html_content
if __name__ == '__main__':
app.run()
**test_hover.py : **
from playwright.sync_api import sync_playwright
def test_hover_element():
with sync_playwright() as playwright:
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto("http://127.0.0.1:5000/")
# Add code to locate the input field and hover over it
input_field_selector = 'input#inputField'
input_field = page.wait_for_selector(input_field_selector)
input_field.hover()
page.wait_for_timeout(5000)
# Add code to wait for the additional text element to appear
additional_text_selector = '.warning'
additional_text = page.wait_for_selector(additional_text_selector)
# Check if the additional text element is displayed
is_displayed = additional_text.is_visible()
if is_displayed:
print("Additional text is displayed on hover!")
else:
print("Additional text is not displayed on hover.")
browser.close()
test_hover_element()
Additional Details : Python 3.11.3 Playwright Version 1.35.0
When I tried to run the above provided code, it gives a playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
.
The logs also mention :
waiting for locator(".warning") to be visible
One more thing, I did this in both headless=True and headless=False mode. In headless=False, I can see that the warning is not being displayed. However, when I manually move the mouse over the input, I can see the hover text and in that case, the test run succeeds. However, that defeats the purpose of using playwright for automation.
Also, note that I added page.wait_for_timeout(5000)
just to see if warning text is displayed in headless=False mode.
Additionally, instead of using input_field.hover()
, I also tried :
1)
box = input_field.bounding_box()
page.mouse.move(box["x"]+box["width"]/2, box["y"]+box["height"]/2)
box = input_field.bounding_box()
page.mouse.click(box["x"]+box["width"]/2, box["y"]+box["height"]/2)
input_field.dispatch_event('hover')
I modified your code to use locator instead of wait_for_selector, which is not necessary as the locator() method automatically waits for the selector to be visible. It seems to run and execute as expected, both headed and headless. I also added an expect to have text.
from playwright.sync_api import sync_playwright, expect
def test_hover_element():
with sync_playwright() as playwright:
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto('http://127.0.0.1:5000/')
input_field = page.locator('input#inputField')
warning_text = page.locator('.warning')
input_field.hover()
if warning_text.is_visible():
print('Additional text is displayed on hover!')
expect(warning_text).to_have_text('Please enter a valid value.')
else:
print('Additional text is not displayed on hover.')
browser.close()
test_hover_element()