# Copyright (c) Microsoft Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import asyncio import datetime import re import pytest from playwright.async_api import Browser, Error, Page, expect from tests.server import Server async def test_assertions_page_to_have_title(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("new title") await expect(page).to_have_title("new title") await expect(page).to_have_title(re.compile("new title")) with pytest.raises(AssertionError): await expect(page).to_have_title("not the current title", timeout=750) with pytest.raises(AssertionError): await expect(page).to_have_title(re.compile("not the current title"), timeout=750) with pytest.raises(AssertionError): await expect(page).not_to_have_title(re.compile("new title"), timeout=750) with pytest.raises(AssertionError): await expect(page).not_to_have_title("new title", timeout=750) await expect(page).not_to_have_title("great title", timeout=750) await page.evaluate( """ setTimeout(() => { document.title = 'great title'; }, 2000); """ ) await expect(page).to_have_title("great title") await expect(page).to_have_title(re.compile("great title")) async def test_assertions_page_to_have_url(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await expect(page).to_have_url(server.EMPTY_PAGE) await expect(page).to_have_url(re.compile(r".*/empty\.html")) with pytest.raises(AssertionError): await expect(page).to_have_url("nooooo", timeout=750) with pytest.raises(AssertionError): await expect(page).to_have_url(re.compile("not-the-url"), timeout=750) await page.evaluate( """ setTimeout(() => { window.location = window.location.origin + '/grid.html'; }, 2000); """ ) await expect(page).to_have_url(server.PREFIX + "/grid.html") await expect(page).not_to_have_url(server.EMPTY_PAGE, timeout=750) with pytest.raises(AssertionError): await expect(page).not_to_have_url(re.compile(r".*/grid\.html"), timeout=750) with pytest.raises(AssertionError): await expect(page).not_to_have_url(server.PREFIX + "/grid.html", timeout=750) await expect(page).to_have_url(re.compile(r".*/grid\.html")) await expect(page).not_to_have_url("**/empty.html", timeout=750) async def test_assertions_page_to_have_url_with_base_url(browser: Browser, server: Server) -> None: page = await browser.new_page(base_url=server.PREFIX) await page.goto("/empty.html") await expect(page).to_have_url("/empty.html") await expect(page).to_have_url(re.compile(r".*/empty\.html")) await page.close() async def test_assertions_page_to_have_url_support_ignore_case(page: Page) -> None: await page.goto("data:text/html,
A
") await expect(page).to_have_url("DATA:teXT/HTml,
a
", ignore_case=True) async def test_assertions_locator_to_contain_text(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div#foobar")).to_contain_text("kek") await expect(page.locator("div#foobar")).not_to_contain_text("bar", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div#foobar")).to_contain_text("bar", timeout=100) await page.set_content("
Text \n1
Text2
Text3
") await expect(page.locator("div")).to_contain_text(["ext 1", re.compile("ext3")]) async def test_assertions_locator_to_contain_text_should_throw_if_arg_is_unsupported_type( page: Page, ) -> None: with pytest.raises(Error, match="value must be a string or regular expression"): await expect(page.locator("div")).to_contain_text(1) # type: ignore async def test_assertions_locator_to_have_attribute(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div#foobar")).to_have_attribute("id", "foobar") await expect(page.locator("div#foobar")).to_have_attribute("id", re.compile("foobar")) await expect(page.locator("div#foobar")).not_to_have_attribute("id", "kek", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div#foobar")).to_have_attribute("id", "koko", timeout=100) async def test_assertions_locator_to_have_attribute_ignore_case(page: Page, server: Page) -> None: await page.set_content("
Text content
") locator = page.locator("#NoDe") await expect(locator).to_have_attribute("id", "node", ignore_case=True) await expect(locator).not_to_have_attribute("id", "node") async def test_assertions_locator_to_have_class(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div.foobar")).to_have_class("foobar") await expect(page.locator("div.foobar")).to_have_class(["foobar"]) await expect(page.locator("div.foobar")).to_have_class(re.compile("foobar")) await expect(page.locator("div.foobar")).to_have_class([re.compile("foobar")]) await expect(page.locator("div.foobar")).not_to_have_class("kekstar", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_class("oh-no", timeout=100) async def test_assertions_locator_to_have_count(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
kek
") await expect(page.locator("div.foobar")).to_have_count(2) await expect(page.locator("div.foobar")).not_to_have_count(42, timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_count(42, timeout=100) async def test_assertions_locator_to_have_css(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div.foobar")).to_have_css("color", "rgb(234, 74, 90)") await expect(page.locator("div.foobar")).not_to_have_css( "color", "rgb(42, 42, 42)", timeout=100 ) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_css( "color", "rgb(42, 42, 42)", timeout=100 ) async def test_assertions_locator_to_have_id(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div.foobar")).to_have_id("kek") await expect(page.locator("div.foobar")).not_to_have_id("top", timeout=100) with pytest.raises(AssertionError): await expect(page.locator("div.foobar")).to_have_id("top", timeout=100) async def test_assertions_locator_to_have_js_property(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
") await page.eval_on_selector( "div", "e => e.foo = { a: 1, b: 'string', c: new Date(1627503992000) }" ) await expect(page.locator("div")).to_have_js_property( "foo", { "a": 1, "b": "string", "c": datetime.datetime.fromtimestamp(1627503992000 / 1000), }, ) async def test_to_have_js_property_pass_string(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = 'string'") locator = page.locator("div") await expect(locator).to_have_js_property("foo", "string") async def test_to_have_js_property_fail_string(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = 'string'") locator = page.locator("div") with pytest.raises(AssertionError): await expect(locator).to_have_js_property("foo", "error", timeout=500) async def test_to_have_js_property_pass_number(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = 2021") locator = page.locator("div") await expect(locator).to_have_js_property("foo", 2021) async def test_to_have_js_property_fail_number(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = 2021") locator = page.locator("div") with pytest.raises(AssertionError): await expect(locator).to_have_js_property("foo", 1, timeout=500) async def test_to_have_js_property_pass_boolean(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = true") locator = page.locator("div") await expect(locator).to_have_js_property("foo", True) async def test_to_have_js_property_fail_boolean(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = false") locator = page.locator("div") with pytest.raises(AssertionError): await expect(locator).to_have_js_property("foo", True, timeout=500) async def test_to_have_js_property_pass_boolean_2(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = false") locator = page.locator("div") await expect(locator).to_have_js_property("foo", False) async def test_to_have_js_property_fail_boolean_2(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = false") locator = page.locator("div") with pytest.raises(AssertionError): await expect(locator).to_have_js_property("foo", True, timeout=500) async def test_to_have_js_property_pass_null(page: Page) -> None: await page.set_content("
") await page.eval_on_selector("div", "e => e.foo = null") locator = page.locator("div") await expect(locator).to_have_js_property("foo", None) async def test_assertions_locator_to_have_text(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
kek
") await expect(page.locator("div#foobar")).to_have_text("kek") await expect(page.locator("div#foobar")).not_to_have_text("top", timeout=100) await page.set_content("
Text \n1
Text 2a
") # Should only normalize whitespace in the first item. await expect(page.locator("div")).to_have_text(["Text 1", re.compile(r"Text \d+a")]) @pytest.mark.parametrize( "method", ["to_have_text", "to_contain_text"], ) async def test_ignore_case(page: Page, server: Server, method: str) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
apple BANANA
orange
") await getattr(expect(page.locator("div#target")), method)("apple BANANA") await getattr(expect(page.locator("div#target")), method)("apple banana", ignore_case=True) # defaults false with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div#target")), method)("apple banana", timeout=300) expected_error_msg = method.replace("_", " ") assert expected_error_msg in str(excinfo.value) # Array Variants await getattr(expect(page.locator("div")), method)(["apple BANANA", "orange"]) await getattr(expect(page.locator("div")), method)(["apple banana", "ORANGE"], ignore_case=True) # defaults false with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div")), method)(["apple banana", "ORANGE"], timeout=300) assert expected_error_msg in str(excinfo.value) # not variant await getattr(expect(page.locator("div#target")), f"not_{method}")("apple banana") with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div#target")), f"not_{method}")( "apple banana", ignore_case=True, timeout=300 ) assert f"not {expected_error_msg}" in str(excinfo) @pytest.mark.parametrize( "method", ["to_have_text", "to_contain_text"], ) async def test_ignore_case_regex(page: Page, server: Server, method: str) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("
apple BANANA
orange
") await getattr(expect(page.locator("div#target")), method)(re.compile("apple BANANA")) await getattr(expect(page.locator("div#target")), method)( re.compile("apple banana"), ignore_case=True ) # defaults to regex flag with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div#target")), method)( re.compile("apple banana"), timeout=300 ) expected_error_msg = method.replace("_", " ") assert expected_error_msg in str(excinfo.value) # overrides regex flag with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div#target")), method)( re.compile("apple banana", re.IGNORECASE), ignore_case=False, timeout=300 ) assert expected_error_msg in str(excinfo.value) # Array Variants await getattr(expect(page.locator("div")), method)( [re.compile("apple BANANA"), re.compile("orange")] ) await getattr(expect(page.locator("div")), method)( [re.compile("apple banana"), re.compile("ORANGE")], ignore_case=True ) # defaults regex flag with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div")), method)( [re.compile("apple banana"), re.compile("ORANGE")], timeout=300 ) assert expected_error_msg in str(excinfo.value) # overrides regex flag with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div")), method)( [ re.compile("apple banana", re.IGNORECASE), re.compile("ORANGE", re.IGNORECASE), ], ignore_case=False, timeout=300, ) assert expected_error_msg in str(excinfo.value) # not variant await getattr(expect(page.locator("div#target")), f"not_{method}")(re.compile("apple banana")) with pytest.raises(AssertionError) as excinfo: await getattr(expect(page.locator("div#target")), f"not_{method}")( re.compile("apple banana"), ignore_case=True, timeout=300 ) assert f"not {expected_error_msg}" in str(excinfo) async def test_assertions_locator_to_have_value(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("") my_input = page.locator("#foo") await expect(my_input).to_have_value("") await expect(my_input).not_to_have_value("bar", timeout=100) await my_input.fill("kektus") await expect(my_input).to_have_value("kektus") async def test_to_have_values_works_with_text(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("select") await locator.select_option(["R", "G"]) await expect(locator).to_have_values(["R", "G"]) async def test_to_have_values_follows_labels(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("text=Pick a Color") await locator.select_option(["R", "G"]) await expect(locator).to_have_values(["R", "G"]) async def test_to_have_values_exact_match_with_text(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("select") await locator.select_option(["RR", "GG"]) with pytest.raises(AssertionError) as excinfo: await expect(locator).to_have_values(["R", "G"], timeout=500) assert "Locator expected to have Values '['R', 'G']'" in str(excinfo.value) assert "Actual value: ['RR', 'GG']" in str(excinfo.value) async def test_to_have_values_works_with_regex(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("select") await locator.select_option(["R", "G"]) await expect(locator).to_have_values([re.compile("R"), re.compile("G")]) async def test_to_have_values_fails_when_items_not_selected(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("select") await locator.select_option(["B"]) with pytest.raises(AssertionError) as excinfo: await expect(locator).to_have_values(["R", "G"], timeout=500) assert "Locator expected to have Values '['R', 'G']'" in str(excinfo.value) assert "Actual value: ['B']" in str(excinfo.value) async def test_to_have_values_fails_when_multiple_not_specified(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("select") await locator.select_option(["B"]) # Assertion failures surface as AssertionError now, not playwright.Error. with pytest.raises(AssertionError) as excinfo: await expect(locator).to_have_values(["R", "G"], timeout=500) assert "Error: Not a select element with a multiple attribute" in str(excinfo.value) async def test_to_have_values_fails_when_not_a_select_element(page: Page, server: Server) -> None: await page.set_content( """ """ ) locator = page.locator("input") with pytest.raises(AssertionError) as excinfo: await expect(locator).to_have_values(["R", "G"], timeout=500) assert "Error: Not a select element with a multiple attribute" in str(excinfo.value) async def test_assertions_locator_to_be_checked(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("") my_checkbox = page.locator("input") await expect(my_checkbox).not_to_be_checked() with pytest.raises(AssertionError): await expect(my_checkbox).to_be_checked(timeout=100) await expect(my_checkbox).to_be_checked(timeout=100, checked=False) with pytest.raises(AssertionError): await expect(my_checkbox).to_be_checked(timeout=100, checked=True) await my_checkbox.check() await expect(my_checkbox).to_be_checked(timeout=100, checked=True) with pytest.raises(AssertionError): await expect(my_checkbox).to_be_checked(timeout=100, checked=False) await expect(my_checkbox).to_be_checked() async def test_assertions_locator_to_be_disabled_enabled(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) await page.set_content("") my_checkbox = page.locator("input") await expect(my_checkbox).not_to_be_disabled() await expect(my_checkbox).to_be_enabled() with pytest.raises(AssertionError): await expect(my_checkbox).to_be_disabled(timeout=100) await my_checkbox.evaluate("e => e.disabled = true") await expect(my_checkbox).to_be_disabled() with pytest.raises(AssertionError): await expect(my_checkbox).to_be_enabled(timeout=100) async def test_assertions_locator_to_be_editable(page: Page, server: Server) -> None: await page.goto(server.EMPTY_PAGE) # A