From ef3d9e870e0d88b99878f20e1c4914d70643e105 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Tue, 2 Apr 2024 14:05:00 +0200 Subject: [PATCH 1/5] [rb][java][dotnet][py] Skipping Edge tests due to https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743 --- dotnet/test/common/ClearTest.cs | 2 ++ dotnet/test/common/ElementFindingTest.cs | 8 ++++++++ java/test/org/openqa/selenium/ClearTest.java | 3 +++ .../org/openqa/selenium/ElementFindingTest.java | 17 +++++++++++++++++ .../selenium/webdriver/common/clear_tests.py | 2 ++ .../common/driver_element_finding_tests.py | 17 +++++++++++++++++ .../webdriver/common/webdriverwait_tests.py | 1 + .../selenium/webdriver/driver_spec.rb | 2 +- 8 files changed, 51 insertions(+), 1 deletion(-) diff --git a/dotnet/test/common/ClearTest.cs b/dotnet/test/common/ClearTest.cs index 15a43f0c8f8cc5..bf094fe68035a3 100644 --- a/dotnet/test/common/ClearTest.cs +++ b/dotnet/test/common/ClearTest.cs @@ -17,6 +17,7 @@ public void WritableTextInputShouldClear() [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void TextInputShouldNotClearWhenDisabled() { driver.Url = readOnlyPage; @@ -44,6 +45,7 @@ public void WritableTextAreaShouldClear() [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void TextAreaShouldNotClearWhenDisabled() { driver.Url = readOnlyPage; diff --git a/dotnet/test/common/ElementFindingTest.cs b/dotnet/test/common/ElementFindingTest.cs index 24c64e9c744680..2fbd7058ef4baf 100644 --- a/dotnet/test/common/ElementFindingTest.cs +++ b/dotnet/test/common/ElementFindingTest.cs @@ -439,6 +439,7 @@ public void ShouldThrowAnExceptionWhenThereIsNoLinkToClick() [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDriverFindElement() { driver.Url = formsPage; @@ -447,6 +448,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidIn [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDriverFindElements() { if (TestUtilities.IsIE6(driver)) @@ -461,6 +463,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidIn [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInElementFindElement() { driver.Url = formsPage; @@ -470,6 +473,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidIn [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInElementFindElements() { driver.Url = formsPage; @@ -479,6 +483,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidIn [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFindElement() { driver.Url = formsPage; @@ -487,6 +492,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriver [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFindElements() { if (TestUtilities.IsIE6(driver)) @@ -501,6 +507,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriver [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElementFindElement() { driver.Url = formsPage; @@ -511,6 +518,7 @@ public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElemen [Test] [IgnoreBrowser(Browser.Chrome, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] + [IgnoreBrowser(Browser.Edge, "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")] public void ShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElementFindElements() { if (TestUtilities.IsIE6(driver)) diff --git a/java/test/org/openqa/selenium/ClearTest.java b/java/test/org/openqa/selenium/ClearTest.java index 0e35d8909489af..5b607606a9cd8e 100644 --- a/java/test/org/openqa/selenium/ClearTest.java +++ b/java/test/org/openqa/selenium/ClearTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.IE; import org.junit.jupiter.api.Test; @@ -39,6 +40,7 @@ void testWritableTextInputShouldClear() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testTextInputShouldNotClearWhenDisabled() { driver.get(pages.readOnlyPage); WebElement element = driver.findElement(By.id("textInputNotEnabled")); @@ -63,6 +65,7 @@ void testWritableTextAreaShouldClear() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testTextAreaShouldNotClearWhenDisabled() { driver.get(pages.readOnlyPage); WebElement element = driver.findElement(By.id("textAreaNotEnabled")); diff --git a/java/test/org/openqa/selenium/ElementFindingTest.java b/java/test/org/openqa/selenium/ElementFindingTest.java index 02b45bcc8b07d0..2fd7345c4174db 100644 --- a/java/test/org/openqa/selenium/ElementFindingTest.java +++ b/java/test/org/openqa/selenium/ElementFindingTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.openqa.selenium.testing.drivers.Browser.CHROME; +import static org.openqa.selenium.testing.drivers.Browser.EDGE; import static org.openqa.selenium.testing.drivers.Browser.FIREFOX; import static org.openqa.selenium.testing.drivers.Browser.IE; import static org.openqa.selenium.testing.drivers.Browser.SAFARI; @@ -100,6 +101,7 @@ void testShouldNotBeAbleToLocateByIdMultipleElementsThatDoNotExist() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingASingleElementByEmptyIdShouldThrow() { driver.get(pages.formPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -108,6 +110,7 @@ void testFindingASingleElementByEmptyIdShouldThrow() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") public void testFindingMultipleElementsByEmptyIdShouldThrow() { driver.get(pages.formPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -318,6 +321,7 @@ void testShouldNotFindElementByClassWhenTheNameQueriedIsShorterThanCandidateName @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingASingleElementByEmptyClassNameShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -326,6 +330,7 @@ void testFindingASingleElementByEmptyClassNameShouldThrow() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingMultipleElementsByEmptyClassNameShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -439,6 +444,7 @@ void testShouldThrowAnExceptionWhenThereIsNoLinkToClick() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDriverFindElement() { driver.get(pages.formPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -447,6 +453,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDri @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDriverFindElements() { driver.get(pages.formPage); @@ -456,6 +463,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDri @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInElementFindElement() { driver.get(pages.formPage); @@ -466,6 +474,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDri @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInElementFindElements() { driver.get(pages.formPage); @@ -476,6 +485,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathIsSyntacticallyInvalidInDri @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFindElement() { driver.get(pages.formPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -484,6 +494,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFin @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFindElements() { driver.get(pages.formPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -492,6 +503,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInDriverFin @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElementFindElement() { driver.get(pages.formPage); @@ -502,6 +514,7 @@ void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElementFi @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testShouldThrowInvalidSelectorExceptionWhenXPathReturnsWrongTypeInElementFindElements() { driver.get(pages.formPage); WebElement body = driver.findElement(By.tagName("body")); @@ -582,6 +595,7 @@ void testShouldNotFindElementsByCssSelectorWhenThereIsNoSuchElement() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingASingleElementByEmptyCssSelectorShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -590,6 +604,7 @@ void testFindingASingleElementByEmptyCssSelectorShouldThrow() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingMultipleElementsByEmptyCssSelectorShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -598,6 +613,7 @@ void testFindingMultipleElementsByEmptyCssSelectorShouldThrow() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingASingleElementByInvalidCssSelectorShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) @@ -606,6 +622,7 @@ void testFindingASingleElementByInvalidCssSelectorShouldThrow() { @Test @Ignore(value = CHROME, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") + @Ignore(value = EDGE, reason = "https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") void testFindingMultipleElementsByInvalidCssSelectorShouldThrow() { driver.get(pages.xhtmlTestPage); assertThatExceptionOfType(InvalidSelectorException.class) diff --git a/py/test/selenium/webdriver/common/clear_tests.py b/py/test/selenium/webdriver/common/clear_tests.py index e3f5c7460f5973..737dd0b44dbdd4 100644 --- a/py/test/selenium/webdriver/common/clear_tests.py +++ b/py/test/selenium/webdriver/common/clear_tests.py @@ -29,6 +29,7 @@ def test_writable_text_input_should_clear(driver, pages): @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_text_input_should_not_clear_when_disabled(driver, pages): pages.load("readOnlyPage.html") element = driver.find_element(By.ID, "textInputNotEnabled") @@ -52,6 +53,7 @@ def test_writable_text_area_should_clear(driver, pages): @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_text_area_should_not_clear_when_disabled(driver, pages): pages.load("readOnlyPage.html") element = driver.find_element(By.ID, "textAreaNotEnabled") diff --git a/py/test/selenium/webdriver/common/driver_element_finding_tests.py b/py/test/selenium/webdriver/common/driver_element_finding_tests.py index bf7c892032607f..2fd0db32b96e3a 100644 --- a/py/test/selenium/webdriver/common/driver_element_finding_tests.py +++ b/py/test/selenium/webdriver/common/driver_element_finding_tests.py @@ -194,6 +194,7 @@ def test_should_not_be_able_to_locate_by_tag_name_multiple_elements_that_do_not_ @pytest.mark.xfail_remote(reason="https://github.com/mozilla/geckodriver/issues/2007") @pytest.mark.xfail_safari(reason="unlike chrome, safari raises NoSuchElementException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_asingle_element_by_empty_tag_name_should_throw(driver, pages): pages.load("formPage.html") with pytest.raises(InvalidSelectorException): @@ -204,6 +205,7 @@ def test_finding_asingle_element_by_empty_tag_name_should_throw(driver, pages): @pytest.mark.xfail_remote(reason="https://github.com/mozilla/geckodriver/issues/2007") @pytest.mark.xfail_safari(reason="unlike chrome, safari returns an empty list") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_multiple_elements_by_empty_tag_name_should_throw(driver, pages): pages.load("formPage.html") with pytest.raises(InvalidSelectorException): @@ -279,6 +281,7 @@ def test_should_not_find_element_by_class_when_the_name_queried_is_shorter_than_ @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_asingle_element_by_empty_class_name_should_throw(driver, pages): pages.load("xhtmlTest.html") msg = r"\/errors#invalid-selector-exception" @@ -302,6 +305,7 @@ def test_finding_asingle_element_by_compound_class_name_should_throw(driver, pag @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_asingle_element_by_invalid_class_name_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): @@ -310,6 +314,7 @@ def test_finding_asingle_element_by_invalid_class_name_should_throw(driver, page @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_multiple_elements_by_invalid_class_name_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): @@ -394,6 +399,7 @@ def test_should_throw_an_exception_when_there_is_no_link_to_click(driver, pages) @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_element( driver, pages ): @@ -404,6 +410,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_elements( driver, pages ): @@ -414,6 +421,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_element( driver, pages ): @@ -425,6 +433,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_elements( driver, pages ): @@ -436,6 +445,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_driver_find_element(driver, pages): pages.load("formPage.html") with pytest.raises(InvalidSelectorException): @@ -444,6 +454,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_i @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_driver_find_elements(driver, pages): pages.load("formPage.html") with pytest.raises(InvalidSelectorException): @@ -452,6 +463,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_i @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_element_find_element(driver, pages): pages.load("formPage.html") body = driver.find_element(By.TAG_NAME, "body") @@ -461,6 +473,7 @@ def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_i @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_element_find_elements(driver, pages): pages.load("formPage.html") body = driver.find_element(By.TAG_NAME, "body") @@ -534,6 +547,7 @@ def test_should_not_find_elements_by_css_selector_when_there_is_no_such_element( @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_asingle_element_by_empty_css_selector_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): @@ -542,6 +556,7 @@ def test_finding_asingle_element_by_empty_css_selector_should_throw(driver, page @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_multiple_elements_by_empty_css_selector_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): @@ -550,6 +565,7 @@ def test_finding_multiple_elements_by_empty_css_selector_should_throw(driver, pa @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_asingle_element_by_invalid_css_selector_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): @@ -558,6 +574,7 @@ def test_finding_asingle_element_by_invalid_css_selector_should_throw(driver, pa @pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException") @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_finding_multiple_elements_by_invalid_css_selector_should_throw(driver, pages): pages.load("xhtmlTest.html") with pytest.raises(InvalidSelectorException): diff --git a/py/test/selenium/webdriver/common/webdriverwait_tests.py b/py/test/selenium/webdriver/common/webdriverwait_tests.py index f08067f8fd9d34..14019d185e8b01 100644 --- a/py/test/selenium/webdriver/common/webdriverwait_tests.py +++ b/py/test/selenium/webdriver/common/webdriverwait_tests.py @@ -34,6 +34,7 @@ def throw_sere(driver): @pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") +@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743") def test_should_fail_with_invalid_selector_exception(driver, pages): pages.load("dynamic.html") with pytest.raises(InvalidSelectorException): diff --git a/rb/spec/integration/selenium/webdriver/driver_spec.rb b/rb/spec/integration/selenium/webdriver/driver_spec.rb index 7352e5ce482451..e478e66d886787 100644 --- a/rb/spec/integration/selenium/webdriver/driver_spec.rb +++ b/rb/spec/integration/selenium/webdriver/driver_spec.rb @@ -148,7 +148,7 @@ module WebDriver end it 'raises if invalid locator', - exclude: {browser: %i[safari safari_preview chrome], + exclude: {browser: %i[safari safari_preview chrome edge], reason: 'Safari TimeoutError + https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743'} do driver.navigate.to url_for('xhtmlTest.html') expect { From a169d905b4215f41d0b04ed18bcf02e3057298a7 Mon Sep 17 00:00:00 2001 From: Sri Harsha Date: Tue, 2 Apr 2024 20:59:16 +0530 Subject: [PATCH 2/5] [JS][bidi] Impelments functionality to retrieve all top-level browsing contexts --- .../bidi/browsingContext.js | 26 +++++++++++++++++++ .../test/bidi/browsingcontext_test.js | 13 +++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index eb9bb881601462..ec22aff2e296a5 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -154,6 +154,32 @@ class BrowsingContext { return new BrowsingContextInfo(result['context'], result['url'], result['children'], result['parent']) } + /** + * @returns {Promise>} A Promise that resolves to an array of BrowsingContextInfo objects representing the top-level browsing contexts. + */ + async getTopLevelContexts() { + const params = { + method: 'browsingContext.getTree', + params: {}, + } + + let result = await this.bidi.send(params) + if ('error' in result) { + throw Error(result['error']) + } + + const contexts = result['result']['contexts']; + const browsingContexts = contexts.map(context => { + return new BrowsingContextInfo( + context['id'], + context['url'], + context['children'], + context['parent'] + ); + }); + return browsingContexts; + } + /** * Closes the browsing context * @returns {Promise} diff --git a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js index 1c7094accc2cbb..52488babb02df5 100644 --- a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js @@ -447,7 +447,18 @@ suite( const devicePixelRatio = await driver.executeScript('return window.devicePixelRatio;') assert.equal(devicePixelRatio, 5) - }) + }); + + it('Get All Top level browsing contexts', async ()=> { + const id = await driver.getWindowHandle() + const window1 = await BrowsingContext(driver, { + browsingContextId: id, + }); + const window2 = await BrowsingContext(driver, {type: 'window'}); + + const res = await window1.getTopLevelContexts(); + assert.equal(res.length, 2); + }); }) }, { browsers: [Browser.FIREFOX] }, From a663d280de741cd56bf40a52f361dc4815b6dfb9 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Tue, 2 Apr 2024 22:18:30 +0200 Subject: [PATCH 3/5] [js] Running format script --- .../selenium-webdriver/bidi/browsingContext.js | 15 +++++---------- .../test/bidi/browsingcontext_test.js | 14 +++++++------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index ec22aff2e296a5..da0b58f8576200 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -168,16 +168,11 @@ class BrowsingContext { throw Error(result['error']) } - const contexts = result['result']['contexts']; - const browsingContexts = contexts.map(context => { - return new BrowsingContextInfo( - context['id'], - context['url'], - context['children'], - context['parent'] - ); - }); - return browsingContexts; + const contexts = result['result']['contexts'] + const browsingContexts = contexts.map((context) => { + return new BrowsingContextInfo(context['id'], context['url'], context['children'], context['parent']) + }) + return browsingContexts } /** diff --git a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js index 52488babb02df5..d2b7e7a2d5407b 100644 --- a/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/browsingcontext_test.js @@ -447,18 +447,18 @@ suite( const devicePixelRatio = await driver.executeScript('return window.devicePixelRatio;') assert.equal(devicePixelRatio, 5) - }); + }) - it('Get All Top level browsing contexts', async ()=> { + it('Get All Top level browsing contexts', async () => { const id = await driver.getWindowHandle() const window1 = await BrowsingContext(driver, { browsingContextId: id, - }); - const window2 = await BrowsingContext(driver, {type: 'window'}); + }) + const window2 = await BrowsingContext(driver, { type: 'window' }) - const res = await window1.getTopLevelContexts(); - assert.equal(res.length, 2); - }); + const res = await window1.getTopLevelContexts() + assert.equal(res.length, 2) + }) }) }, { browsers: [Browser.FIREFOX] }, From 37565afc7243047c961d9330aba1c39ec0b5240f Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Wed, 3 Apr 2024 01:13:30 +0300 Subject: [PATCH 4/5] [dotnet] Simplify definition of building test web server for unit tests --- .../test/common/WebDriver.Common.Tests.csproj | 22 ++----------------- ...WebDriver.Common.Tests.csproj.prebuild.cmd | 2 -- .../WebDriver.Common.Tests.csproj.prebuild.sh | 3 --- 3 files changed, 2 insertions(+), 25 deletions(-) delete mode 100644 dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.cmd delete mode 100755 dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.sh diff --git a/dotnet/test/common/WebDriver.Common.Tests.csproj b/dotnet/test/common/WebDriver.Common.Tests.csproj index 4f8946ba069bec..1a8c95ee51d79d 100644 --- a/dotnet/test/common/WebDriver.Common.Tests.csproj +++ b/dotnet/test/common/WebDriver.Common.Tests.csproj @@ -6,16 +6,6 @@ OpenQA.Selenium - - - - - - - - - - @@ -37,22 +27,14 @@ - - - - Always - - - - - - + + diff --git a/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.cmd b/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.cmd deleted file mode 100644 index 7d569e3fbec726..00000000000000 --- a/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.cmd +++ /dev/null @@ -1,2 +0,0 @@ -echo Building test web server -bazel build //java/test/org/openqa/selenium/environment:appserver_deploy.jar diff --git a/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.sh b/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.sh deleted file mode 100755 index d692e821c93a31..00000000000000 --- a/dotnet/test/common/WebDriver.Common.Tests.csproj.prebuild.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -echo "Building test web server" -bazel build //java/test/org/openqa/selenium/environment:appserver_deploy.jar From 911b31209015852a5aa7b851de2d878e1e615070 Mon Sep 17 00:00:00 2001 From: Puja Jagani Date: Wed, 3 Apr 2024 10:05:52 +0530 Subject: [PATCH 5/5] [js] Add JS comments for BiDi related files (#13763) --- .../bidi/addInterceptParameters.js | 26 ++ .../node/selenium-webdriver/bidi/browser.js | 17 + .../bidi/browsingContext.js | 134 ++++++- .../bidi/browsingContextInspector.js | 51 +++ .../bidi/browsingContextTypes.js | 31 ++ .../bidi/captureScreenshotParameters.js | 32 ++ .../selenium-webdriver/bidi/clipRectangle.js | 40 ++ .../bidi/continueRequestParameters.js | 39 ++ .../bidi/continueResponseParameters.js | 40 ++ .../selenium-webdriver/bidi/cookieFilter.js | 60 +++ .../selenium-webdriver/bidi/evaluateResult.js | 17 + .../node/selenium-webdriver/bidi/input.js | 26 ++ .../selenium-webdriver/bidi/interceptPhase.js | 4 + .../selenium-webdriver/bidi/logEntries.js | 66 ++++ .../node/selenium-webdriver/bidi/network.js | 102 +++++ .../selenium-webdriver/bidi/networkTypes.js | 347 +++++++++++++++++- .../selenium-webdriver/bidi/partialCookie.js | 50 ++- .../bidi/partitionDescriptor.js | 32 ++ .../selenium-webdriver/bidi/partitionKey.js | 17 + .../selenium-webdriver/bidi/protocolType.js | 20 + .../selenium-webdriver/bidi/protocolValue.js | 131 ++++++- .../bidi/provideResponseParameters.js | 40 ++ .../node/selenium-webdriver/bidi/realmInfo.js | 27 ++ .../bidi/resultOwnership.js | 4 + .../selenium-webdriver/bidi/scriptManager.js | 118 +++++- .../selenium-webdriver/bidi/scriptTypes.js | 38 ++ .../node/selenium-webdriver/bidi/storage.js | 30 ++ .../selenium-webdriver/bidi/urlPattern.js | 35 ++ 28 files changed, 1565 insertions(+), 9 deletions(-) diff --git a/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js b/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js index c2170526bf43e5..56d5f77aaedb43 100644 --- a/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js +++ b/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js @@ -29,6 +29,13 @@ class AddInterceptParameters { } } + /** + * Adds a URL pattern to intercept. + * + * @param {UrlPattern} pattern - The URL pattern to add. + * @returns {AddInterceptParameters} - Returns the current instance of the class AddInterceptParameters for chaining. + * @throws {Error} - Throws an error if the pattern is not an instance of UrlPattern. + */ urlPattern(pattern) { if (!(pattern instanceof UrlPattern)) { throw new Error(`Pattern must be an instance of UrlPattern. Received: '${pattern})'`) @@ -37,6 +44,13 @@ class AddInterceptParameters { return this } + /** + * Adds array of URL patterns to intercept. + * + * @param {UrlPattern[]} patterns - An array of UrlPattern instances representing the URL patterns to intercept. + * @returns {AddInterceptParameters} - Returns the instance of AddInterceptParameters for chaining. + * @throws {Error} - Throws an error if the pattern is not an instance of UrlPattern. + */ urlPatterns(patterns) { patterns.forEach((pattern) => { if (!(pattern instanceof UrlPattern)) { @@ -47,6 +61,13 @@ class AddInterceptParameters { return this } + /** + * Adds string URL to intercept. + * + * @param {string} pattern - The URL pattern to be added. + * @returns {AddInterceptParameters} - Returns the instance of AddInterceptParameters for chaining.. + * @throws {Error} - If the pattern is not an instance of String. + */ urlStringPattern(pattern) { if (!(pattern instanceof String)) { throw new Error(`Pattern must be an instance of String. Received:'${pattern}'`) @@ -56,6 +77,11 @@ class AddInterceptParameters { return this } + /** + * Adds array of string URLs to intercept. + * @param {string[]} patterns - An array of URL string patterns. + * @returns {this} - Returns the instance of AddInterceptParameters for chaining. + */ urlStringPatterns(patterns) { patterns.forEach((pattern) => { if (!(pattern instanceof String)) { diff --git a/javascript/node/selenium-webdriver/bidi/browser.js b/javascript/node/selenium-webdriver/bidi/browser.js index 0ac48ce61e6f12..4c36d7552627e4 100644 --- a/javascript/node/selenium-webdriver/bidi/browser.js +++ b/javascript/node/selenium-webdriver/bidi/browser.js @@ -15,6 +15,10 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents the commands and events under Browser Module. + * Described in https://w3c.github.io/webdriver-bidi/#module-browser + */ class Browser { constructor(driver) { this._driver = driver @@ -28,6 +32,10 @@ class Browser { this.bidi = await this._driver.getBidi() } + /** + * Creates a new user context. + * @returns {Promise} A promise that resolves to the user context id. + */ async createUserContext() { const command = { method: 'browser.createUserContext', @@ -39,6 +47,10 @@ class Browser { return response.result.userContext } + /** + * Gets the list of all user contexts. + * @returns {Promise} A promise that resolves to an array of user context ids. + */ async getUserContexts() { const command = { method: 'browser.getUserContexts', @@ -58,6 +70,11 @@ class Browser { return userContexts } + /** + * Removes a user context. + * @param {string} userContext The user context id to be removed. + * @returns {Promise} + */ async removeUserContext(userContext) { const command = { method: 'browser.removeUserContext', diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index da0b58f8576200..cc9f11b76fa855 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -21,6 +21,10 @@ const { SerializationOptions, ReferenceValue, RemoteValue } = require('./protoco const { WebElement } = require('../lib/webdriver') const { CaptureScreenshotParameters } = require('./captureScreenshotParameters') +/** + * Represents the locator to locate nodes in the browsing context. + * Described in https://w3c.github.io/webdriver-bidi/#type-browsingContext-Locator. + */ class Locator { static Type = Object.freeze({ CSS: 'css', @@ -42,14 +46,35 @@ class Locator { this.#maxDepth = maxDepth } + /** + * Creates a new Locator object with CSS selector type. + * + * @param {string} value - The CSS selector value. + * @returns {Locator} A new Locator object with CSS selector type. + */ static css(value) { return new Locator(Locator.Type.CSS, value) } + /** + * Creates a new Locator object with the given XPath value. + * + * @param {string} value - The XPath value. + * @returns {Locator} A new Locator object. + */ static xpath(value) { return new Locator(Locator.Type.XPATH, value) } + /** + * Creates a new Locator object with the specified inner text value. + * + * @param {string} value - The inner text value to locate. + * @param {boolean|undefined} [ignoreCase] - Whether to ignore the case when matching the inner text value. + * @param {string|undefined} [matchType] - The type of matching to perform (full or partial). + * @param {number|undefined} [maxDepth] - The maximum depth to search for the inner text value. + * @returns {Locator} A new Locator object with the specified inner text value. + */ static innerText(value, ignoreCase = undefined, matchType = undefined, maxDepth = undefined) { return new Locator(Locator.Type.INNER_TEXT, value, ignoreCase, matchType, maxDepth) } @@ -67,6 +92,12 @@ class Locator { } } +/** + * Represents the contains under BrowsingContext module commands. + * Described in https://w3c.github.io/webdriver-bidi/#module-browsingContext + * Each browsing context command requires a browsing context id. + * Hence, this class represent browsing context lifecycle. + */ class BrowsingContext { constructor(driver) { this._driver = driver @@ -225,6 +256,13 @@ class BrowsingContext { return new PrintResult(response.result.data) } + /** + * Captures a screenshot of the browsing context. + * + * @param {CaptureScreenshotParameters|undefined} [captureScreenshotParameters] - Optional parameters for capturing the screenshot. + * @returns {Promise} - A promise that resolves to the base64-encoded string representation of the captured screenshot. + * @throws {InvalidArgumentError} - If the provided captureScreenshotParameters is not an instance of CaptureScreenshotParameters. + */ async captureScreenshot(captureScreenshotParameters = undefined) { if ( captureScreenshotParameters !== undefined && @@ -273,6 +311,12 @@ class BrowsingContext { return response['result']['data'] } + /** + * Captures a screenshot of a specific element within the browsing context. + * @param {string} sharedId - The shared ID of the element to capture. + * @param {string} [handle] - The handle of the element to capture (optional). + * @returns {Promise} A promise that resolves to the base64-encoded screenshot data. + */ async captureElementScreenshot(sharedId, handle = undefined) { let params = { method: 'browsingContext.captureScreenshot', @@ -307,6 +351,11 @@ class BrowsingContext { } } + /** + * Activates and focuses the top-level browsing context. + * @returns {Promise} A promise that resolves when the browsing context is activated. + * @throws {Error} If there is an error while activating the browsing context. + */ async activate() { const params = { method: 'browsingContext.activate', @@ -321,6 +370,13 @@ class BrowsingContext { } } + /** + * Handles a user prompt in the browsing context. + * + * @param {boolean} [accept] - Optional. Indicates whether to accept or dismiss the prompt. + * @param {string} [userText] - Optional. The text to enter. + * @throws {Error} If an error occurs while handling the user prompt. + */ async handleUserPrompt(accept = undefined, userText = undefined) { const params = { method: 'browsingContext.handleUserPrompt', @@ -337,6 +393,15 @@ class BrowsingContext { } } + /** + * Reloads the current browsing context. + * + * @param {boolean} [ignoreCache] - Whether to ignore the cache when reloading. + * @param {string} [readinessState] - The readiness state to wait for before returning. + * Valid readiness states are 'none', 'interactive', and 'complete'. + * @returns {Promise} - A promise that resolves to the result of the reload operation. + * @throws {Error} - If an invalid readiness state is provided. + */ async reload(ignoreCache = undefined, readinessState = undefined) { if (readinessState !== undefined && !['none', 'interactive', 'complete'].includes(readinessState)) { throw Error(`Valid readiness states are 'none', 'interactive' & 'complete'. Received: ${readinessState}`) @@ -355,6 +420,13 @@ class BrowsingContext { return new NavigateResult(navigateResult['url'], navigateResult['navigation']) } + /** + * Sets the viewport size and device pixel ratio for the browsing context. + * @param {number} width - The width of the viewport. + * @param {number} height - The height of the viewport. + * @param {number} [devicePixelRatio] - The device pixel ratio (optional) + * @throws {Error} If an error occurs while setting the viewport. + */ async setViewport(width, height, devicePixelRatio = undefined) { const params = { method: 'browsingContext.setViewport', @@ -370,6 +442,12 @@ class BrowsingContext { } } + /** + * Traverses the browsing context history by a given delta. + * + * @param {number} delta - The delta value to traverse the history. A positive value moves forward, while a negative value moves backward. + * @returns {Promise} - A promise that resolves when the history traversal is complete. + */ async traverseHistory(delta) { const params = { method: 'browsingContext.traverseHistory', @@ -381,14 +459,38 @@ class BrowsingContext { await this.bidi.send(params) } + /** + * Moves the browsing context forward by one step in the history. + * @returns {Promise} A promise that resolves when the browsing context has moved forward. + */ async forward() { await this.traverseHistory(1) } + /** + * Navigates the browsing context to the previous page in the history. + * @returns {Promise} A promise that resolves when the navigation is complete. + */ async back() { await this.traverseHistory(-1) } + /** + * Locates nodes in the browsing context. + * + * @param {Locator} locator - The locator object used to locate the nodes. + * @param {number} [maxNodeCount] - The maximum number of nodes to locate (optional). + * @param {string} [ownership] - The ownership type of the nodes (optional). + * @param {string} [sandbox] - The sandbox name for locating nodes (optional). + * @param {SerializationOptions} [serializationOptions] - The serialization options for locating nodes (optional). + * @param {ReferenceValue[]} [startNodes] - The array of start nodes for locating nodes (optional). + * @returns {Promise} - A promise that resolves to the arrays of located nodes. + * @throws {Error} - If the locator is not an instance of Locator. + * @throws {Error} - If the serializationOptions is provided but not an instance of SerializationOptions. + * @throws {Error} - If the ownership is provided but not 'root' or 'none'. + * @throws {Error} - If the startNodes is provided but not an array of ReferenceValue objects. + * @throws {Error} - If any of the startNodes is not an instance of ReferenceValue. + */ async locateNodes( locator, maxNodeCount = undefined, @@ -448,6 +550,16 @@ class BrowsingContext { return remoteValues } + /** + * Locates a single node in the browsing context. + * + * @param {Locator} locator - The locator used to find the node. + * @param {string} [ownership] - The ownership of the node (optional). + * @param {string} [sandbox] - The sandbox of the node (optional). + * @param {SerializationOptions} [serializationOptions] - The serialization options for the node (optional). + * @param {Array} [startNodes] - The starting nodes for the search (optional). + * @returns {Promise} - A promise that resolves to the located node. + */ async locateNode( locator, ownership = undefined, @@ -475,26 +587,44 @@ class BrowsingContext { } } +/** + * Represents the result of a navigation operation. + */ class NavigateResult { constructor(url, navigationId) { this._url = url this._navigationId = navigationId } + /** + * Gets the URL of the navigated page. + * @returns {string} The URL of the navigated page. + */ get url() { return this._url } + /** + * Gets the ID of the navigation operation. + * @returns {number} The ID of the navigation operation. + */ get navigationId() { return this._navigationId } } +/** + * Represents a print result. + */ class PrintResult { constructor(data) { this._data = data } + /** + * Gets the data associated with the print result. + * @returns {any} The data associated with the print result. + */ get data() { return this._data } @@ -514,9 +644,5 @@ async function getBrowsingContextInstance(driver, { browsingContextId, type, ref return instance } -/** - * API - * @type {function(*, {*,*,*}): Promise} - */ module.exports = getBrowsingContextInstance module.exports.Locator = Locator diff --git a/javascript/node/selenium-webdriver/bidi/browsingContextInspector.js b/javascript/node/selenium-webdriver/bidi/browsingContextInspector.js index 94bb253d8903e5..36ff2f5a86f74f 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContextInspector.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContextInspector.js @@ -17,6 +17,12 @@ const { BrowsingContextInfo, NavigationInfo } = require('./browsingContextTypes') +/** + * Represents a browsing context related events. + * Described in https://w3c.github.io/webdriver-bidi/#module-contexts-events. + * While BrowsingContext class represents a browsing context lifecycle and related commands. + * This class is specific to listening to events. Events can be subscribed to multiple browsing contexts or all of them. + */ class BrowsingContextInspector { constructor(driver, browsingContextIds) { this._driver = driver @@ -27,34 +33,79 @@ class BrowsingContextInspector { this.bidi = await this._driver.getBidi() } + /** + * Subscribes to the 'browsingContext.contextCreated' event. + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onBrowsingContextCreated(callback) { await this.subscribeAndHandleEvent('browsingContext.contextCreated', callback) } + /** + * Subscribes to the 'browsingContext.contextDestroyed' event. + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onBrowsingContextDestroyed(callback) { await this.subscribeAndHandleEvent('browsingContext.contextDestroyed', callback) } + /** + * Subscribe to the 'browsingContext.navigationStarted' event. + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onNavigationStarted(callback) { await this.subscribeAndHandleEvent('browsingContext.navigationStarted', callback) } + /** + * Subscribes to the 'browsingContext.fragmentNavigated' event. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onFragmentNavigated(callback) { await this.subscribeAndHandleEvent('browsingContext.fragmentNavigated', callback) } + /** + * Subscribes to the 'browsingContext.userPromptClosed' event. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onUserPromptClosed(callback) { await this.subscribeAndHandleEvent('browsingContext.userPromptClosed', callback) } + /** + * Subscribes to the 'browsingContext.userPromptOpened' event. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onUserPromptOpened(callback) { await this.subscribeAndHandleEvent('browsingContext.userPromptOpened', callback) } + /** + * Subscribes to the 'browsingContext.domContentLoaded' event. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onDomContentLoaded(callback) { await this.subscribeAndHandleEvent('browsingContext.domContentLoaded', callback) } + /** + * Subscribes to the 'browsingContext.load' event. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the event is emitted. + */ async onBrowsingContextLoaded(callback) { await this.subscribeAndHandleEvent('browsingContext.load', callback) } diff --git a/javascript/node/selenium-webdriver/bidi/browsingContextTypes.js b/javascript/node/selenium-webdriver/bidi/browsingContextTypes.js index 0ce3ded6595bdf..77dbd6343aea57 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContextTypes.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContextTypes.js @@ -15,6 +15,10 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents information about a browsing context. + * Described in https://w3c.github.io/webdriver-bidi/#type-browsingContext-Info + */ class BrowsingContextInfo { constructor(id, url, children, parentBrowsingContext) { this._id = id @@ -23,24 +27,51 @@ class BrowsingContextInfo { this._parentBrowsingContext = parentBrowsingContext } + /** + * Get the ID of the browsing context. + * @returns {string} The ID of the browsing context. + */ get id() { return this._id } + /** + * Get the URL of the browsing context. + * @returns {string} The URL of the browsing context. + */ get url() { return this._url } + /** + * Get the children of the browsing context. + * @returns {Array} The children of the browsing context. + */ get children() { return this._children } + /** + * Get the parent browsing context. + * @returns {BrowsingContextInfo} The parent browsing context. + */ get parentBrowsingContext() { return this._parentBrowsingContext } } +/** + * Represents information about a navigation. + * Described in https://w3c.github.io/webdriver-bidi/#type-browsingContext-NavigationInfo. + */ class NavigationInfo { + /** + * Constructs a new NavigationInfo object. + * @param {string} browsingContextId - The ID of the browsing context. + * @param {string} navigationId - The ID of the navigation. + * @param {number} timestamp - The timestamp of the navigation. + * @param {string} url - The URL of the page navigated to. + */ constructor(browsingContextId, navigationId, timestamp, url) { this.browsingContextId = browsingContextId this.navigationId = navigationId diff --git a/javascript/node/selenium-webdriver/bidi/captureScreenshotParameters.js b/javascript/node/selenium-webdriver/bidi/captureScreenshotParameters.js index a894f1d89314f8..eafdb40c5ba98d 100644 --- a/javascript/node/selenium-webdriver/bidi/captureScreenshotParameters.js +++ b/javascript/node/selenium-webdriver/bidi/captureScreenshotParameters.js @@ -16,14 +16,31 @@ // under the License. const { BoxClipRectangle, ElementClipRectangle } = require('./clipRectangle') + +/** + * Defines the reference point from which to compute offsets for capturing screenshot. + * + * @enum {string} + */ const Origin = { VIEWPORT: 'viewport', DOCUMENT: 'document', } +/** + * Represents the optional parameters for capturing a screenshot. + * Described in https://w3c.github.io/webdriver-bidi/#command-browsingContext-captureScreenshot. + */ class CaptureScreenshotParameters { #map = new Map() + /** + * Sets the origin for capturing the screenshot. + * + * @param {Origin} origin - The origin for capturing the screenshot. Must be one of `Origin.VIEWPORT` or `Origin.DOCUMENT`. + * @returns {CaptureScreenshotParameters} - The current instance of the CaptureScreenshotParameters for chaining. + * @throws {Error} - If the provided origin is not valid. + */ origin(origin) { if (origin !== Origin.VIEWPORT && origin !== Origin.DOCUMENT) { throw new Error(`Origin must be one of ${Object.values(Origin)}. Received:'${origin}'`) @@ -32,6 +49,14 @@ class CaptureScreenshotParameters { return this } + /** + * Sets the image format and quality for capturing a screenshot. + * + * @param {string} type - The image format type. + * @param {number} [quality] - The image quality (optional). + * @throws {Error} If the type is not a string or if the quality is not a number. + * @returns {CaptureScreenshotParameters} - The current instance of the CaptureScreenshotParameters for chaining. + */ imageFormat(type, quality = undefined) { if (typeof type !== 'string') { throw new Error(`Type must be an instance of String. Received:'${type}'`) @@ -48,6 +73,13 @@ class CaptureScreenshotParameters { return this } + /** + * Sets the clip rectangle for capturing a screenshot. + * + * @param {BoxClipRectangle|ElementClipRectangle} clipRectangle - The clip rectangle to set. + * @throws {Error} If the clipRectangle is not an instance of ClipRectangle. + * @returns {CaptureScreenshotParameters} - The current instance of the CaptureScreenshotParameters for chaining. + */ clipRectangle(clipRectangle) { if (!(clipRectangle instanceof BoxClipRectangle || clipRectangle instanceof ElementClipRectangle)) { throw new Error(`ClipRectangle must be an instance of ClipRectangle. Received:'${clipRectangle}'`) diff --git a/javascript/node/selenium-webdriver/bidi/clipRectangle.js b/javascript/node/selenium-webdriver/bidi/clipRectangle.js index 272cc7d3284454..67552032911810 100644 --- a/javascript/node/selenium-webdriver/bidi/clipRectangle.js +++ b/javascript/node/selenium-webdriver/bidi/clipRectangle.js @@ -15,13 +15,25 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents a clip rectangle. + * Described in https://w3c.github.io/webdriver-bidi/#command-browsingContext-captureScreenshot. + */ class ClipRectangle { clipType + /** + * Constructs a new ClipRectangle object. + * @param {string} type - The type of the clip rectangle. + */ constructor(type) { this.clipType = type } + /** + * Gets the type of the clip rectangle. + * @returns {string} The type of the clip rectangle. + */ get type() { return this.clipType } @@ -29,10 +41,19 @@ class ClipRectangle { asMap() {} } +/** + * Represents a clip rectangle for an element. + * @extends ClipRectangle + */ class ElementClipRectangle extends ClipRectangle { #sharedId #handleId + /** + * Constructs a new ElementClipRectangle instance. + * @param {string} sharedId - The shared ID of the element. + * @param {string} [handleId] - The handle ID of the element (optional). + */ constructor(sharedId, handleId = undefined) { super('element') this.#sharedId = sharedId @@ -42,6 +63,10 @@ class ElementClipRectangle extends ClipRectangle { } } + /** + * Converts the ElementClipRectangle instance to a map. + * @returns {Map} - The converted map. + */ asMap() { const map = new Map() map.set('type', super.type) @@ -58,12 +83,23 @@ class ElementClipRectangle extends ClipRectangle { } } +/** + * Represents a box-shaped clip rectangle. + * @extends ClipRectangle + */ class BoxClipRectangle extends ClipRectangle { #x #y #width #height + /** + * Constructs a new BoxClipRectangle object. + * @param {number} x - The x-coordinate of the top-left corner of the rectangle. + * @param {number} y - The y-coordinate of the top-left corner of the rectangle. + * @param {number} width - The width of the rectangle. + * @param {number} height - The height of the rectangle. + */ constructor(x, y, width, height) { super('box') this.#x = x @@ -72,6 +108,10 @@ class BoxClipRectangle extends ClipRectangle { this.#height = height } + /** + * Converts the BoxClipRectangle object to a Map. + * @returns {Map} - The Map representation of the BoxClipRectangle object. + */ asMap() { const map = new Map() map.set('type', super.type) diff --git a/javascript/node/selenium-webdriver/bidi/continueRequestParameters.js b/javascript/node/selenium-webdriver/bidi/continueRequestParameters.js index b6051d0e1e2547..622fd358466700 100644 --- a/javascript/node/selenium-webdriver/bidi/continueRequestParameters.js +++ b/javascript/node/selenium-webdriver/bidi/continueRequestParameters.js @@ -17,6 +17,10 @@ const { BytesValue, Header } = require('./networkTypes') +/** + * Represents the parameters for a continue request command. + * Described in https://w3c.github.io/webdriver-bidi/#command-network-continueRequest. + */ class ContinueRequestParameters { #map = new Map() @@ -24,6 +28,13 @@ class ContinueRequestParameters { this.#map.set('request', request) } + /** + * Sets the body value for the request. + * + * @param {BytesValue} value - The value to set as the body. Must be an instance of BytesValue. + * @returns {ContinueRequestParameters} - The current instance of the ContinueRequestParameters for chaining. + * @throws {Error} - If the value is not an instance of BytesValue. + */ body(value) { if (!(value instanceof BytesValue)) { throw new Error(`Value must be an instance of BytesValue. Received: '${value})'`) @@ -32,6 +43,13 @@ class ContinueRequestParameters { return this } + /** + * Sets the cookies for the request. + * + * @param {Header[]} cookieHeaders - An array of cookie headers. + * @returns {continueRequestParameters} - The current instance of the ContinueRequestParameters for chaining. + * @throws {Error} - If a cookie header is not an instance of Header. + */ cookies(cookieHeaders) { const cookies = [] cookieHeaders.forEach((header) => { @@ -45,6 +63,13 @@ class ContinueRequestParameters { return this } + /** + * Sets the headers for the request. + * + * @param {Header[]} headers - An array of Header objects. + * @returns {ContinueRequestParameters} - The current instance of the ContinueRequestParameters for chaining. + * @throws {Error} - If the header value is not an instance of Header. + */ headers(headers) { const headerList = [] headers.forEach((header) => { @@ -58,6 +83,13 @@ class ContinueRequestParameters { return this } + /** + * Sets the HTTP method for the request. + * + * @param {string} method - The HTTP method to be set. + * @returns {ContinueRequestParameters} - The updated `continueRequestParameters` object. + * @throws {Error} - If the method parameter is not a string. + */ method(method) { if (typeof method !== 'string') { throw new Error(`Http method must be a string. Received: '${method})'`) @@ -66,6 +98,13 @@ class ContinueRequestParameters { return this } + /** + * Sets the URL for the request. + * + * @param {string} url - The URL to set for the request. + * @returns {ContinueRequestParameters} - The current instance of the ContinueRequestParameters for chaining. + * @throws {Error} - If the url parameter is not a string. + */ url(url) { if (typeof url !== 'string') { throw new Error(`Url must be a string. Received:'${url}'`) diff --git a/javascript/node/selenium-webdriver/bidi/continueResponseParameters.js b/javascript/node/selenium-webdriver/bidi/continueResponseParameters.js index 1cfba8d105c308..cac65fa1c2ea41 100644 --- a/javascript/node/selenium-webdriver/bidi/continueResponseParameters.js +++ b/javascript/node/selenium-webdriver/bidi/continueResponseParameters.js @@ -17,6 +17,10 @@ const { Header } = require('./networkTypes') +/** + * Represents the parameters for a continue response. + * Described in https://w3c.github.io/webdriver-bidi/#command-network-continueResponse. + */ class ContinueResponseParameters { #map = new Map() @@ -24,6 +28,13 @@ class ContinueResponseParameters { this.#map.set('request', request) } + /** + * Sets the cookies for the response. + * + * @param {Header[]} cookieHeaders - The array of cookie headers. + * @returns {ContinueResponseParameters} - The current instance of the ContinueResponseParameters for chaining. + * @throws {Error} - If the cookieHeader is not an instance of Header. + */ cookies(cookieHeaders) { const cookies = [] cookieHeaders.forEach((header) => { @@ -37,6 +48,14 @@ class ContinueResponseParameters { return this } + /** + * Sets the credentials for authentication. + * + * @param {string} username - The username for authentication. + * @param {string} password - The password for authentication. + * @returns {ContinueResponseParameters} The current instance of the ContinueResponseParameters for chaining. + * @throws {Error} If username or password is not a string. + */ credentials(username, password) { if (typeof username !== 'string') { throw new Error(`Username must be a string. Received:'${username}'`) @@ -51,6 +70,13 @@ class ContinueResponseParameters { return this } + /** + * Sets the headers for the response. + * + * @param {Header[]} headers - An array of Header objects representing the headers. + * @returns {ContinueResponseParameters} - The current instance of the ContinueResponseParameters for chaining. + * @throws {Error} - If the header value is not an instance of Header. + */ headers(headers) { const headerList = [] headers.forEach((header) => { @@ -64,6 +90,13 @@ class ContinueResponseParameters { return this } + /** + * Sets the reason phrase for the response. + * + * @param {string} reasonPhrase - The reason phrase for the response. + * @returns {ContinueResponseParameters} - The current instance of the ContinueResponseParameters for chaining. + * @throws {Error} - If the reason phrase is not a string. + */ reasonPhrase(reasonPhrase) { if (typeof reasonPhrase !== 'string') { throw new Error(`Reason phrase must be a string. Received: '${reasonPhrase})'`) @@ -72,6 +105,13 @@ class ContinueResponseParameters { return this } + /** + * Sets the status code for the response. + * + * @param {number} statusCode - The status code to set. + * @returns {ContinueResponseParameters} - The current instance of the ContinueResponseParameters for chaining. + * @throws {Error} - If the `statusCode` parameter is not an integer. + */ statusCode(statusCode) { if (!Number.isInteger(statusCode)) { throw new Error(`Status must be an integer. Received:'${statusCode}'`) diff --git a/javascript/node/selenium-webdriver/bidi/cookieFilter.js b/javascript/node/selenium-webdriver/bidi/cookieFilter.js index 5dc4b61ec64381..08651ec2cb0d8f 100644 --- a/javascript/node/selenium-webdriver/bidi/cookieFilter.js +++ b/javascript/node/selenium-webdriver/bidi/cookieFilter.js @@ -17,14 +17,31 @@ const { SameSite, BytesValue } = require('./networkTypes') +/** + * Represents a filter for fetching cookies. + * Described in https://w3c.github.io/webdriver-bidi/#command-storage-getCookies + */ class CookieFilter { #map = new Map() + /** + * Sets the name of the cookie. + * + * @param {string} name - The name of the cookie. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ name(name) { this.#map.set('name', name) return this } + /** + * Sets the value of the cookie. + * + * @param {BytesValue} value - The value to be set. Must be an instance of BytesValue. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + * @throws {Error} - If the value is not an instance of BytesValue. + */ value(value) { if (!(value instanceof BytesValue)) { throw new Error(`Value must be an instance of BytesValue. Received:'${value}'`) @@ -33,31 +50,68 @@ class CookieFilter { return this } + /** + * Sets the domain for the cookie. + * + * @param {string} domain - The domain to set. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ domain(domain) { this.#map.set('domain', domain) return this } + /** + * Sets the url path for the cookie to be fetched. + * + * @param {string} path - The url path for the cookie to be fetched. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ path(path) { this.#map.set('path', path) return this } + /** + * Sets the size of the cookie to be fetched. + * + * @param {number} size - The size of the cookie. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ size(size) { this.#map.set('size', size) return this } + /** + * Sets the `httpOnly` flag for the cookie filter. + * + * @param {boolean} httpOnly - The value to set for the `httpOnly` flag. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ httpOnly(httpOnly) { this.#map.set('httpOnly', httpOnly) return this } + /** + * Sets the flag to fetch secure cookies. + * + * @param {boolean} secure - Whether the cookie fetched should be secure only or not. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ secure(secure) { this.#map.set('secure', secure) return this } + /** + * Sets the SameSite attribute for the cookie. + * + * @param {SameSite} sameSite - The SameSite value to be set for the cookie. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + * @throws {Error} - If the provided sameSite value is not an instance of SameSite. + */ sameSite(sameSite) { if (!(sameSite instanceof SameSite)) { throw new Error(`Params must be a value in SameSite. Received:'${sameSite}'`) @@ -66,6 +120,12 @@ class CookieFilter { return this } + /** + * Sets the expiry value. + * + * @param {number} expiry - The expiry value. + * @returns {CookieFilter} - The updated CookieFilter instance for chaining. + */ expiry(expiry) { this.#map.set('expiry', expiry) return this diff --git a/javascript/node/selenium-webdriver/bidi/evaluateResult.js b/javascript/node/selenium-webdriver/bidi/evaluateResult.js index 1f7288896d74b7..c4a4327f585854 100644 --- a/javascript/node/selenium-webdriver/bidi/evaluateResult.js +++ b/javascript/node/selenium-webdriver/bidi/evaluateResult.js @@ -15,11 +15,20 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents the type of script evaluation result. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-EvaluateResult. + * @enum {string} + */ const EvaluateResultType = { SUCCESS: 'success', EXCEPTION: 'exception', } +/** + * Represents a successful evaluation result. + * @class + */ class EvaluateResultSuccess { constructor(realmId, value) { this.resultType = EvaluateResultType.SUCCESS @@ -28,6 +37,10 @@ class EvaluateResultSuccess { } } +/** + * Represents an exception that occurred during evaluation of a result. + * @class + */ class EvaluateResultException { constructor(realmId, exceptionDetails) { this.resultType = EvaluateResultType.EXCEPTION @@ -36,6 +49,10 @@ class EvaluateResultException { } } +/** + * Represents details of an exception. + * @class + */ class ExceptionDetails { constructor(exceptionDetails) { this.columnNumber = 'columnNumber' in exceptionDetails ? exceptionDetails['columnNumber'] : null diff --git a/javascript/node/selenium-webdriver/bidi/input.js b/javascript/node/selenium-webdriver/bidi/input.js index 88477457b62501..1f16a192354977 100644 --- a/javascript/node/selenium-webdriver/bidi/input.js +++ b/javascript/node/selenium-webdriver/bidi/input.js @@ -20,6 +20,10 @@ const { WebElement } = require('../lib/webdriver') const { RemoteReferenceType, ReferenceValue } = require('./protocolValue') +/** + * Represents commands and events related to the Input module (simulated user input). + * Described in https://w3c.github.io/webdriver-bidi/#module-input. + */ class Input { constructor(driver) { this._driver = driver @@ -33,6 +37,13 @@ class Input { this.bidi = await this._driver.getBidi() } + /** + * Performs the specified actions on the given browsing context. + * + * @param {string} browsingContextId - The ID of the browsing context. + * @param {Array} actions - The actions to be performed. + * @returns {Promise} A promise that resolves with the response from the server. + */ async perform(browsingContextId, actions) { const _actions = await updateActions(actions) @@ -49,6 +60,12 @@ class Input { return response } + /** + * Resets the input state in the specified browsing context. + * + * @param {string} browsingContextId - The ID of the browsing context. + * @returns {Promise} A promise that resolves when the release actions are sent. + */ async release(browsingContextId) { const command = { method: 'input.releaseActions', @@ -59,6 +76,15 @@ class Input { return await this.bidi.send(command) } + /** + * Sets the files property of a given input element. + * + * @param {string} browsingContextId - The ID of the browsing context. + * @param {string | ReferenceValue} element - The ID of the element or a ReferenceValue object representing the element. + * @param {string | string[]} files - The file path or an array of file paths to be set. + * @throws {Error} If the element is not a string or a ReferenceValue. + * @returns {Promise} A promise that resolves when the files are set. + */ async setFiles(browsingContextId, element, files) { if (typeof element !== 'string' && !(element instanceof ReferenceValue)) { throw Error(`Pass in a WebElement id as a string or a ReferenceValue. Received: ${element}`) diff --git a/javascript/node/selenium-webdriver/bidi/interceptPhase.js b/javascript/node/selenium-webdriver/bidi/interceptPhase.js index fd18eb770f4449..cfe6279e8fe960 100644 --- a/javascript/node/selenium-webdriver/bidi/interceptPhase.js +++ b/javascript/node/selenium-webdriver/bidi/interceptPhase.js @@ -15,6 +15,10 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents the different phases of intercepting network requests and responses. + * @enum {string} + */ const InterceptPhase = { BEFORE_REQUEST_SENT: 'beforeRequestSent', RESPONSE_STARTED: 'responseStarted', diff --git a/javascript/node/selenium-webdriver/bidi/logEntries.js b/javascript/node/selenium-webdriver/bidi/logEntries.js index 59a38705b1b189..ed78d285a9f449 100644 --- a/javascript/node/selenium-webdriver/bidi/logEntries.js +++ b/javascript/node/selenium-webdriver/bidi/logEntries.js @@ -17,7 +17,18 @@ 'use strict' +/** + * Represents a base log entry. + * Desribed in https://w3c.github.io/webdriver-bidi/#types-log-logentry. + */ class BaseLogEntry { + /** + * Creates a new instance of BaseLogEntry. + * @param {string} level - The log level. + * @param {string} text - The log text. + * @param {number} timeStamp - The log timestamp. + * @param {string} stackTrace - The log stack trace. + */ constructor(level, text, timeStamp, stackTrace) { this._level = level this._text = text @@ -25,34 +36,72 @@ class BaseLogEntry { this._stackTrace = stackTrace } + /** + * Gets the log level. + * @returns {string} The log level. + */ get level() { return this._level } + /** + * Gets the log text. + * @returns {string} The log text. + */ get text() { return this._text } + /** + * Gets the log timestamp. + * @returns {number} The log timestamp. + */ get timeStamp() { return this._timeStamp } + /** + * Gets the log stack trace. + * @returns {string} The log stack trace. + */ get stackTrace() { return this._stackTrace } } +/** + * Represents a generic log entry. + * @class + * @extends BaseLogEntry + */ class GenericLogEntry extends BaseLogEntry { + /** + * Creates an instance of GenericLogEntry. + * @param {string} level - The log level. + * @param {string} text - The log text. + * @param {Date} timeStamp - The log timestamp. + * @param {string} type - The log type. + * @param {string} stackTrace - The log stack trace. + */ constructor(level, text, timeStamp, type, stackTrace) { super(level, text, timeStamp, stackTrace) this._type = type } + /** + * Gets the log type. + * @returns {string} The log type. + */ get type() { return this._type } } +/** + * Represents a log entry for console logs. + * @class + * @extends GenericLogEntry + */ class ConsoleLogEntry extends GenericLogEntry { constructor(level, text, timeStamp, type, method, realm, args, stackTrace) { super(level, text, timeStamp, type, stackTrace) @@ -61,19 +110,36 @@ class ConsoleLogEntry extends GenericLogEntry { this._args = args } + /** + * Gets the method associated with the log entry. + * @returns {string} The method associated with the log entry. + */ get method() { return this._method } + /** + * Gets the realm associated with the log entry. + * @returns {string} The realm associated with the log entry. + */ get realm() { return this._realm } + /** + * Gets the arguments associated with the log entry. + * @returns {Array} The arguments associated with the log entry. + */ get args() { return this._args } } +/** + * Represents a log entry for JavaScript logs. + * @class + * @extends GenericLogEntry + */ class JavascriptLogEntry extends GenericLogEntry { constructor(level, text, timeStamp, type, stackTrace) { super(level, text, timeStamp, type, stackTrace) diff --git a/javascript/node/selenium-webdriver/bidi/network.js b/javascript/node/selenium-webdriver/bidi/network.js index 352f3d69d21f9d..9f0c0ea2a1a87b 100644 --- a/javascript/node/selenium-webdriver/bidi/network.js +++ b/javascript/node/selenium-webdriver/bidi/network.js @@ -21,7 +21,17 @@ const { ContinueResponseParameters } = require('./continueResponseParameters') const { ContinueRequestParameters } = require('./continueRequestParameters') const { ProvideResponseParameters } = require('./provideResponseParameters') +/** + * Represents all commands and events of Network module. + * Described in https://w3c.github.io/webdriver-bidi/#module-network. + */ class Network { + /** + * Represents a Network object. + * @constructor + * @param {Driver} driver - The driver to fetch the BiDi connection. + * @param {Array} browsingContextIds - An array of browsing context IDs that the network events will be subscribed to. + */ constructor(driver, browsingContextIds) { this._driver = driver this._browsingContextIds = browsingContextIds @@ -31,22 +41,52 @@ class Network { this.bidi = await this._driver.getBidi() } + /** + * Subscribes to the 'network.beforeRequestSent' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async beforeRequestSent(callback) { await this.subscribeAndHandleEvent('network.beforeRequestSent', callback) } + /** + * Subscribes to the 'network.responseStarted' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async responseStarted(callback) { await this.subscribeAndHandleEvent('network.responseStarted', callback) } + /** + * Subscribes to the 'network.responseCompleted' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async responseCompleted(callback) { await this.subscribeAndHandleEvent('network.responseCompleted', callback) } + /** + * Subscribes to the 'network.authRequired' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async authRequired(callback) { await this.subscribeAndHandleEvent('network.authRequired', callback) } + /** + * Subscribes to the 'network.fetchError' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async fetchError(callback) { await this.subscribeAndHandleEvent('network.fetchError', callback) } @@ -99,6 +139,13 @@ class Network { }) } + /** + * Adds a network intercept. + * + * @param {AddInterceptParameters} params - The parameters for the network intercept. + * @returns {Promise} - A promise that resolves to the added intercept's id. + * @throws {Error} - If params is not an instance of AddInterceptParameters. + */ async addIntercept(params) { if (!(params instanceof AddInterceptParameters)) { throw new Error(`Params must be an instance of AddInterceptParameters. Received:'${params}'`) @@ -114,6 +161,12 @@ class Network { return response.result.intercept } + /** + * Removes an intercept. + * + * @param {string} interceptId - The ID of the intercept to be removed. + * @returns {Promise} - A promise that resolves when the intercept is successfully removed. + */ async removeIntercept(interceptId) { const command = { method: 'network.removeIntercept', @@ -123,6 +176,13 @@ class Network { await this.bidi.send(command) } + /** + * Continues the network request with authentication credentials. + * @param {string} requestId - The ID of the request to continue. + * @param {string} username - The username for authentication. + * @param {string} password - The password for authentication. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async continueWithAuth(requestId, username, password) { const command = { method: 'network.continueWithAuth', @@ -139,6 +199,12 @@ class Network { await this.bidi.send(command) } + /** + * Fails a network request. + * + * @param {number} requestId - The ID of the request to fail. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async failRequest(requestId) { const command = { method: 'network.failRequest', @@ -149,6 +215,11 @@ class Network { await this.bidi.send(command) } + /** + * Continues the network request with authentication but without providing credentials. + * @param {string} requestId - The ID of the request to continue with authentication. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async continueWithAuthNoCredentials(requestId) { const command = { method: 'network.continueWithAuth', @@ -160,6 +231,12 @@ class Network { await this.bidi.send(command) } + /** + * Cancels the authentication for a specific request. + * + * @param {string} requestId - The ID of the request to cancel authentication for. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async cancelAuth(requestId) { const command = { method: 'network.continueWithAuth', @@ -171,6 +248,13 @@ class Network { await this.bidi.send(command) } + /** + * Continues the network request with the provided parameters. + * + * @param {ContinueRequestParameters} params - The parameters for continuing the request. + * @throws {Error} If params is not an instance of ContinueRequestParameters. + * @returns {Promise} A promise that resolves when the command is sent. + */ async continueRequest(params) { if (!(params instanceof ContinueRequestParameters)) { throw new Error(`Params must be an instance of ContinueRequestParameters. Received:'${params}'`) @@ -184,6 +268,13 @@ class Network { await this.bidi.send(command) } + /** + * Continues the network response with the given parameters. + * + * @param {ContinueResponseParameters} params - The parameters for continuing the response. + * @throws {Error} If params is not an instance of ContinueResponseParameters. + * @returns {Promise} A promise that resolves when the command is sent. + */ async continueResponse(params) { if (!(params instanceof ContinueResponseParameters)) { throw new Error(`Params must be an instance of ContinueResponseParameters. Received:'${params}'`) @@ -197,6 +288,13 @@ class Network { await this.bidi.send(command) } + /** + * Provides a response for the network. + * + * @param {ProvideResponseParameters} params - The parameters for providing the response. + * @throws {Error} If params is not an instance of ProvideResponseParameters. + * @returns {Promise} A promise that resolves when the command is sent. + */ async provideResponse(params) { if (!(params instanceof ProvideResponseParameters)) { throw new Error(`Params must be an instance of ProvideResponseParameters. Received:'${params}'`) @@ -210,6 +308,10 @@ class Network { await this.bidi.send(command) } + /** + * Unsubscribes from network events for all browsing contexts. + * @returns {Promise} A promise that resolves when the network connection is closed. + */ async close() { await this.bidi.unsubscribe( 'network.beforeRequestSent', diff --git a/javascript/node/selenium-webdriver/bidi/networkTypes.js b/javascript/node/selenium-webdriver/bidi/networkTypes.js index 3fb6f180f96af7..8a62aaa5d39645 100644 --- a/javascript/node/selenium-webdriver/bidi/networkTypes.js +++ b/javascript/node/selenium-webdriver/bidi/networkTypes.js @@ -17,6 +17,11 @@ const { NavigationInfo } = require('./browsingContextTypes') +/** + * Represents the possible values for the SameSite attribute of a cookie. + * @enum {string} + */ + const SameSite = { STRICT: 'strict', LAX: 'lax', @@ -31,25 +36,46 @@ const SameSite = { }, } +/** + * Represents a BytesValue object. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-BytesValue. + */ class BytesValue { static Type = { STRING: 'string', BASE64: 'base64', } + /** + * Creates a new BytesValue instance. + * @param {string} type - The type of the BytesValue. + * @param {string} value - The value of the BytesValue. + */ constructor(type, value) { this._type = type this._value = value } + /** + * Gets the type of the BytesValue. + * @returns {string} The type of the BytesValue. + */ get type() { return this._type } + /** + * Gets the value of the BytesValue. + * @returns {string} The value of the BytesValue. + */ get value() { return this._value } + /** + * Converts the BytesValue to a map. + * @returns {Map} A map representation of the BytesValue. + */ asMap() { const map = new Map() map.set('type', this._type) @@ -58,24 +84,47 @@ class BytesValue { } } +/** + * Represents a header with a name and value. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-Header. + */ class Header { + /** + * Creates a new Header instance. + * @param {string} name - The name of the header. + * @param {BytesValue} value - The value of the header. + * @throws {Error} If the value is not an instance of BytesValue. + */ constructor(name, value) { this._name = name if (!(value instanceof BytesValue)) { - throw new Error(`Value must be an instance of BytesValue. Received:'${value}'`) + throw new Error(`Value must be an instance of BytesValue. Received: '${value}'`) } this._value = value } + /** + * Gets the name of the header. + * @returns {string} The name of the header. + */ get name() { return this._name } + /** + * Gets the value of the header. + * @returns {BytesValue} The value of the header. + */ get value() { return this._value } } +/** + * Represents a cookie. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-Cookie. + * @class + */ class Cookie { constructor(name, value, domain, path, size, httpOnly, secure, sameSite, expires) { this._name = name @@ -89,44 +138,85 @@ class Cookie { this._sameSite = sameSite } + /** + * Gets the name of the cookie. + * @returns {string} The name of the cookie. + */ get name() { return this._name } + /** + * Gets the value of the cookie. + * @returns {BytesValue} The value of the cookie. + */ get value() { return this._value } + /** + * Gets the domain of the cookie. + * @returns {string} The domain of the cookie. + */ get domain() { return this._domain } + /** + * Gets the path of the cookie. + * @returns {string} The path of the cookie. + */ get path() { return this._path } + /** + * Gets the expiration date of the cookie. + * @returns {number} The expiration date of the cookie. + */ get expires() { return this._expires } + /** + * Gets the size of the cookie. + * @returns {number} The size of the cookie. + */ get size() { return this._size } + /** + * Checks if the cookie is HTTP-only. + * @returns {boolean} True if the cookie is HTTP-only, false otherwise. + */ get httpOnly() { return this._httpOnly } + /** + * Checks if the cookie is secure. + * @returns {boolean} True if the cookie is secure, false otherwise. + */ get secure() { return this._secure } + /** + * Gets the same-site attribute of the cookie. + * @returns {string} The same-site attribute of the cookie. + */ get sameSite() { return this._sameSite } } // No tests written for FetchTimingInfo. Must be updated after browsers implment it and corresponding WPT test are written. +/** + * Represents the time of each part of the request. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-FetchTimingInfo. + * @class + */ class FetchTimingInfo { constructor( originTime, @@ -158,59 +248,128 @@ class FetchTimingInfo { this._responseEnd = responseEnd } + /** + * Gets the origin time. + * + * @returns {number} The origin time. + */ get originTime() { return this._originTime } + /** + * Get the request time. + * + * @returns {number} The request time. + */ get requestTime() { return this._requestTime } + /** + * Gets the timestamp when the redirect started. + * + * @returns {number} The timestamp when the redirect started. + */ get redirectStart() { return this._redirectStart } + /** + * Gets the timestamp when the redirect ended. + * + * @returns {number} The timestamp when the redirect ended. + */ get redirectEnd() { return this._redirectEnd } + /** + * Gets the timestamp when the fetch started. + * + * @returns {number} The timestamp when the fetch started. + */ get fetchStart() { return this._fetchStart } + /** + * Gets the timestamp when the domain lookup started. + * + * @returns {number} The timestamp when the domain lookup started. + */ get dnsStart() { return this._dnsStart } + /** + * Gets the timestamp when the domain lookup ended. + * + * @returns {number} The timestamp when the domain lookup ended. + */ get dnsEnd() { return this._dnsEnd } + /** + * Gets the timestamp when the connection started. + * + * @returns {number} The timestamp when the connection ended. + */ get connectStart() { return this._connectStart } + /** + * Gets the timestamp when the connection ended. + * + * @returns {number} The timestamp when the connection ended. + */ get connectEnd() { return this._connectEnd } + /** + * Gets the timestamp when the secure connection started. + * + * @returns {number} The timestamp when the secure connection started. + */ get tlsStart() { return this._tlsStart } + /** + * Gets the timestamp when the request started. + * + * @returns {number} The timestamp when the request started. + */ get requestStart() { return this._requestStart } + /** + * Gets the timestamp when the response started. + * + * @returns {number} The timestamp when the response started. + */ get responseStart() { return this._responseStart } + /** + * Gets the timestamp when the response ended. + * + * @returns {number} The timestamp when the response ended. + */ get responseEnd() { return this._responseEnd } } +/** + * Represents the data of a network request. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-RequestData. + */ class RequestData { constructor(request, url, method, headers, cookies, headersSize, bodySize, timings) { this._request = request @@ -257,39 +416,75 @@ class RequestData { ) } + /** + * Get the request id. + * @returns {string} The request id. + */ get request() { return this._request } + /** + * Get the URL of the request. + * @returns {string} The URL of the request. + */ get url() { return this._url } + /** + * Get the HTTP method of the request. + * @returns {string} The HTTP method of the request. + */ get method() { return this._method } + /** + * Get the headers of the request. + * @returns {Header[]} An array of header objects. + */ get headers() { return this._headers } + /** + * Get the cookies of the request. + * @returns {Cookie[]} An array of cookie objects. + */ get cookies() { return this._cookies } + /** + * Get the size of the headers in bytes. + * @returns {number} The size of the headers in bytes. + */ get headersSize() { return this._headersSize } + /** + * Get the size of the request body in bytes. + * @returns {number} The size of the request body in bytes. + */ get bodySize() { return this._bodySize } + /** + * Get the timing information of the request. + * @returns {FetchTimingInfo} The timing information of the request. + */ get timings() { return this._timings } } +/** + * Represents the base parameters for a network request. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-BaseParameters. + */ class BaseParameters { constructor(id, navigation, redirectCount, request, timestamp) { this._id = id @@ -311,28 +506,60 @@ class BaseParameters { this._timestamp = timestamp } + /** + * Gets the browsing context ID of the network request. + * @returns {string|null} The browsing context ID of the network request. + */ get id() { return this._id } + /** + * Gets the navigation information associated with the network request. + * @returns {NavigationInfo|null} The navigation information associated with the network request, or null if not available. + */ get navigation() { return this._navigation } + /** + * Gets the number of redirects that occurred during the network request. + * @returns {number} The number of redirects that occurred during the network request. + */ get redirectCount() { return this._redirectCount } + /** + * Gets the request data for the network request. + * @returns {RequestData} The request data for the network request. + */ get request() { return this._request } + /** + * Gets the timestamp of the network request. + * @returns {number} The timestamp of the network request. + */ get timestamp() { return this._timestamp } } +/** + * Represents source in the network. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-Initiator. + */ class Initiator { + /** + * Constructs a new Initiator instance. + * @param {string} type - The type of the initiator. + * @param {number} columnNumber - The column number. + * @param {number} lineNumber - The line number. + * @param {string} stackTrace - The stack trace. + * @param {string} request - The request id. + */ constructor(type, columnNumber, lineNumber, stackTrace, request) { this._type = type this._columnNumber = columnNumber @@ -341,27 +568,53 @@ class Initiator { this._request = request } + /** + * Gets the type of the initiator. + * @returns {string} The type of the initiator. + */ get type() { return this._type } + /** + * Gets the column number. + * @returns {number} The column number. + */ get columnNumber() { return this._columnNumber } + /** + * Gets the line number. + * @returns {number} The line number. + */ get lineNumber() { return this._lineNumber } + /** + * Gets the stack trace. + * @returns {string} The stack trace. + */ get stackTrace() { return this._stackTrace } + /** + * Gets the request ID. + * @returns {string} The request ID. + */ get request() { return this._request } } +/** + * Represents the BeforeRequestSent event parameters. + * @class + * @extends BaseParameters + * Described in https://w3c.github.io/webdriver-bidi/#event-network-beforeSendRequest. + */ class BeforeRequestSent extends BaseParameters { constructor(id, navigation, redirectCount, request, timestamp, initiator) { super(id, navigation, redirectCount, request, timestamp) @@ -374,22 +627,49 @@ class BeforeRequestSent extends BaseParameters { ) } + /** + * Get the initiator of the request. + * @returns {Initiator} The initiator object. + */ get initiator() { return this._initiator } } +/** + * Represents the FetchError event parameters. + * Described https://w3c.github.io/webdriver-bidi/#event-network-fetchError + * @extends BaseParameters + */ class FetchError extends BaseParameters { + /** + * Creates a new FetchError instance. + * @param {string} id - The ID of the error. + * @param {string} navigation - The navigation information. + * @param {number} redirectCount - The number of redirects. + * @param {RequestData} request - The request object. + * @param {number} timestamp - The timestamp of the error. + * @param {string} errorText - The error text. + */ constructor(id, navigation, redirectCount, request, timestamp, errorText) { super(id, navigation, redirectCount, request, timestamp) this._errorText = errorText } + /** + * Gets the error text. + * @returns {string} The error text. + */ get errorText() { return this._errorText } } +/** + * Represents the response data received from a network request. + * Described in https://w3c.github.io/webdriver-bidi/#type-network-ResponseData. + * @class + */ class ResponseData { constructor( url, @@ -417,51 +697,112 @@ class ResponseData { this._content = content } + /** + * Get the URL. + * + * @returns {string} The URL. + */ get url() { return this._url } + /** + * Get the protocol. + * + * @returns {string} The protocol. + */ get protocol() { return this._protocol } + /** + * Get the HTTP status. + * + * @returns {string} The HTTP status. + */ get status() { return this._status } + /** + * Gets the status text. + * + * @returns {string} The status text. + */ get statusText() { return this._statusText } + /** + * Gets the value indicating whether the data is retrieved from cache. + * + * @returns {boolean} The value indicating whether the data is retrieved from cache. + */ get fromCache() { return this._fromCache } + /** + * Get the headers. + * + * @returns {Object} The headers object. + */ get headers() { return this._headers } + /** + * The MIME type of the network resource. + * + * @type {string} + */ get mimeType() { return this._mimeType } + /** + * Gets the number of bytes received. + * + * @returns {number} The number of bytes received. + */ get bytesReceived() { return this._bytesReceived } + /** + * Get the size of the headers. + * + * @returns {number} The size of the headers. + */ get headerSize() { return this._headersSize } + /** + * Get the size of the body. + * + * @returns {number} The size of the body. + */ get bodySize() { return this._bodySize } + /** + * Gets the content. + * + * @returns {any} The content. + */ get content() { return this._content } } +/** + * Represents the ResponseStarted event parameters. + * Described in https://w3c.github.io/webdriver-bidi/#event-network-responseStarted. + * @class + * @extends BaseParameters + */ class ResponseStarted extends BaseParameters { constructor(id, navigation, redirectCount, request, timestamp, response) { super(id, navigation, redirectCount, request, timestamp) @@ -480,6 +821,10 @@ class ResponseStarted extends BaseParameters { ) } + /** + * Get the response data. + * @returns {ResponseData} The response data. + */ get response() { return this._response } diff --git a/javascript/node/selenium-webdriver/bidi/partialCookie.js b/javascript/node/selenium-webdriver/bidi/partialCookie.js index 218f4df10c96f3..5c74a0fc8a374d 100644 --- a/javascript/node/selenium-webdriver/bidi/partialCookie.js +++ b/javascript/node/selenium-webdriver/bidi/partialCookie.js @@ -15,11 +15,23 @@ // specific language governing permissions and limitations // under the License. -const { BytesValue } = require('./networkTypes') +const { BytesValue, SameSite } = require('./networkTypes') +/** + * Represents a partial cookie used to set cookies. + * Described in https://w3c.github.io/webdriver-bidi/#command-storage-setCookie. + * @class + */ class PartialCookie { #map = new Map() + /** + * Represents a partial cookie. + * @class + * @param {string} name - The name of the cookie. + * @param {BytesValue} value - The value of the cookie as an instance of BytesValue. + * @param {string} domain - The domain of the cookie. + */ constructor(name, value, domain) { this.#map.set('name', name) if (!(value instanceof BytesValue)) { @@ -29,31 +41,67 @@ class PartialCookie { this.#map.set('domain', domain) } + /** + * Sets the path for the cookie. + * + * @param {string} path - The path for the cookie. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ path(path) { this.#map.set('path', path) return this } + /** + * Sets the size of the cookie. + * + * @param {number} size - The size of the cookie. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ size(size) { this.#map.set('size', size) return this } + /** + * Sets the `httpOnly` flag for the cookie. + * + * @param {boolean} httpOnly - The value to set for the `httpOnly` flag. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ httpOnly(httpOnly) { this.#map.set('httpOnly', httpOnly) return this } + /** + * Sets the secure flag for the cookie. + * + * @param {boolean} secure - Indicates whether the cookie should only be sent over secure connections. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ secure(secure) { this.#map.set('secure', secure) return this } + /** + * Sets the SameSite attribute for the cookie. + * + * @param {SameSite} sameSite - The SameSite attribute value for the cookie. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ sameSite(sameSite) { this.#map.set('sameSite', sameSite) return this } + /** + * Sets the expiry for the cookie. + * + * @param {number} expiry - The expiry time of the cookie. + * @returns {PartialCookie} - The updated PartialCookie instance for chaining. + */ expiry(expiry) { this.#map.set('expiry', expiry) return this diff --git a/javascript/node/selenium-webdriver/bidi/partitionDescriptor.js b/javascript/node/selenium-webdriver/bidi/partitionDescriptor.js index 7df84b12998a2e..8efd0d54ed5f99 100644 --- a/javascript/node/selenium-webdriver/bidi/partitionDescriptor.js +++ b/javascript/node/selenium-webdriver/bidi/partitionDescriptor.js @@ -15,19 +15,36 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents the types of partition descriptors. + * @enum {string} + * Described in https://w3c.github.io/webdriver-bidi/#command-storage-getCookies. + */ const Type = { CONTEXT: 'context', STORAGE_KEY: 'storageKey', } +/** + * Represents a partition descriptor. + * Described in https://w3c.github.io/webdriver-bidi/#command-storage-getCookies. + */ class PartitionDescriptor { #type + /** + * Constructs a new PartitionDescriptor instance. + * @param {Type} type - The type of the partition. + */ constructor(type) { this.#type = type } } +/** + * Represents a partition descriptor for a browsing context. + * @extends PartitionDescriptor + */ class BrowsingContextPartitionDescriptor extends PartitionDescriptor { #context = null @@ -44,6 +61,10 @@ class BrowsingContextPartitionDescriptor extends PartitionDescriptor { } } +/** + * Represents a partition descriptor for storage key. + * @extends PartitionDescriptor + */ class StorageKeyPartitionDescriptor extends PartitionDescriptor { #map = new Map() @@ -51,11 +72,22 @@ class StorageKeyPartitionDescriptor extends PartitionDescriptor { super(Type.STORAGE_KEY) } + /** + * Sets the user context for the partition descriptor. + * @param {any} userContext - The user context to set. + * @returns {PartitionDescriptor} - The updated partition descriptor instance for chaining. + */ userContext(userContext) { this.#map.set('userContext', userContext) return this } + /** + * Sets the source origin for the partition descriptor. + * + * @param {string} sourceOrigin - The source origin to set. + * @returns {PartitionDescriptor} - The updated PartitionDescriptor instance for chaining. + */ sourceOrigin(sourceOrigin) { this.#map.set('sourceOrigin', sourceOrigin) return this diff --git a/javascript/node/selenium-webdriver/bidi/partitionKey.js b/javascript/node/selenium-webdriver/bidi/partitionKey.js index 315728e82ee873..de83863136ddf8 100644 --- a/javascript/node/selenium-webdriver/bidi/partitionKey.js +++ b/javascript/node/selenium-webdriver/bidi/partitionKey.js @@ -15,19 +15,36 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents a partition key of cookie storage. + * Described in https://w3c.github.io/webdriver-bidi/#type-storage-PartitionKey. + */ class PartitionKey { #userContext #sourceOrigin + /** + * Constructs a new PartitionKey object. + * @param {string} userContext - The user context. + * @param {string} sourceOrigin - The source origin. + */ constructor(userContext, sourceOrigin) { this.#userContext = userContext this.#sourceOrigin = sourceOrigin } + /** + * Gets the user context. + * @returns {string} The user context. + */ get userContext() { return this.#userContext } + /** + * Gets the source origin. + * @returns {string} The source origin. + */ get sourceOrigin() { return this.#sourceOrigin } diff --git a/javascript/node/selenium-webdriver/bidi/protocolType.js b/javascript/node/selenium-webdriver/bidi/protocolType.js index 6c6a6a3ba26d59..81c578f6c225c9 100644 --- a/javascript/node/selenium-webdriver/bidi/protocolType.js +++ b/javascript/node/selenium-webdriver/bidi/protocolType.js @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents a primitive type. + * @enum + * Described in https://w3c.github.io/webdriver-bidi/#type-script-PrimitiveProtocolValue. + */ const PrimitiveType = { UNDEFINED: 'undefined', NULL: 'null', @@ -33,6 +38,11 @@ const PrimitiveType = { }, } +/** + * Represents a non-primitive type. + * @enum + * Described inhttps://w3c.github.io/webdriver-bidi/#type-script-RemoteValue. + */ const NonPrimitiveType = { ARRAY: 'array', DATE: 'date', @@ -51,6 +61,11 @@ const NonPrimitiveType = { }, } +/** + * Represents a remote value type. + * @enum + * Described inhttps://w3c.github.io/webdriver-bidi/#type-script-RemoteValue. + */ const RemoteType = { SYMBOL: 'symbol', FUNCTION: 'function', @@ -77,6 +92,11 @@ const RemoteType = { }, } +/** + * Represents a speacial number type. + * @enum + * Described in https://w3c.github.io/webdriver-bidi/#type-script-PrimitiveProtocolValue. + */ const SpecialNumberType = { NAN: 'NaN', MINUS_ZERO: '-0', diff --git a/javascript/node/selenium-webdriver/bidi/protocolValue.js b/javascript/node/selenium-webdriver/bidi/protocolValue.js index 825df9fc7fbc0a..1d6f88e822518f 100644 --- a/javascript/node/selenium-webdriver/bidi/protocolValue.js +++ b/javascript/node/selenium-webdriver/bidi/protocolValue.js @@ -19,11 +19,20 @@ const { PrimitiveType, NonPrimitiveType, RemoteType } = require('./protocolType' const TYPE_CONSTANT = 'type' const VALUE_CONSTANT = 'value' +/** + * Represents the types of remote reference. + * @enum {string} + */ const RemoteReferenceType = { HANDLE: 'handle', SHARED_ID: 'sharedId', } +/** + * Represents a local value with a specified type and optional value. + * @class + * Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue + */ class LocalValue { constructor(type, value = null) { if (type === PrimitiveType.UNDEFINED || type === PrimitiveType.NULL) { @@ -34,42 +43,97 @@ class LocalValue { } } + /** + * Creates a new LocalValue object with a string value. + * + * @param {string} value - The string value to be stored in the LocalValue object. + * @returns {LocalValue} - The created LocalValue object. + */ static createStringValue(value) { return new LocalValue(PrimitiveType.STRING, value) } + /** + * Creates a new LocalValue object with a number value. + * + * @param {number} value - The number value. + * @returns {LocalValue} - The created LocalValue object. + */ static createNumberValue(value) { return new LocalValue(PrimitiveType.NUMBER, value) } + /** + * Creates a new LocalValue object with a special number value. + * + * @param {number} value - The value of the special number. + * @returns {LocalValue} - The created LocalValue object. + */ static createSpecialNumberValue(value) { return new LocalValue(PrimitiveType.SPECIAL_NUMBER, value) } + /** + * Creates a new LocalValue object with an undefined value. + * @returns {LocalValue} - The created LocalValue object. + */ static createUndefinedValue() { return new LocalValue(PrimitiveType.UNDEFINED) } + /** + * Creates a new LocalValue object with a null value. + * @returns {LocalValue} - The created LocalValue object. + */ static createNullValue() { return new LocalValue(PrimitiveType.NULL) } + /** + * Creates a new LocalValue object with a boolean value. + * + * @param {boolean} value - The boolean value. + * @returns {LocalValue} - The created LocalValue object. + */ static createBooleanValue(value) { return new LocalValue(PrimitiveType.BOOLEAN, value) } + /** + * Creates a new LocalValue object with a BigInt value. + * + * @param {BigInt} value - The BigInt value. + * @returns {LocalValue} - The created LocalValue object. + */ static createBigIntValue(value) { return new LocalValue(PrimitiveType.BIGINT, value) } + /** + * Creates a new LocalValue object with an array. + * + * @param {Array} value - The array. + * @returns {LocalValue} - The created LocalValue object. + */ static createArrayValue(value) { return new LocalValue(NonPrimitiveType.ARRAY, value) } + /** + * Creates a new LocalValue object with date value. + * + * @param {string} value - The date. + * @returns {LocalValue} - The created LocalValue object. + */ static createDateValue(value) { return new LocalValue(NonPrimitiveType.DATE, value) } + /** + * Creates a new LocalValue object of map value. + * @param {Map} map - The map. + * @returns {LocalValue} - The created LocalValue object. + */ static createMapValue(map) { let value = [] Object.entries(map).forEach((entry) => { @@ -78,22 +142,45 @@ class LocalValue { return new LocalValue(NonPrimitiveType.MAP, value) } - static createObjectValue(map) { + /** + * Creates a new LocalValue object from the passed object. + * + * @param {Object} map - The object. + * @returns {LocalValue} - The created LocalValue object. + */ + static createObjectValue(object) { let value = [] - Object.entries(map).forEach((entry) => { + Object.entries(object).forEach((entry) => { value.push(entry) }) return new LocalValue(NonPrimitiveType.OBJECT, value) } + /** + * Creates a new LocalValue object of regular expression value. + * + * @param {string} value - The value of the regular expression. + * @returns {LocalValue} - The created LocalValue object. + */ static createRegularExpressionValue(value) { return new LocalValue(NonPrimitiveType.REGULAR_EXPRESSION, value) } + /** + * Creates a new LocalValue object with the specified value. + * @param {Set} value - The value to be set. + * @returns {LocalValue} - The created LocalValue object. + */ static createSetValue(value) { return new LocalValue(NonPrimitiveType.SET, value) } + /** + * Creates a new LocalValue object with the given channel value + * + * @param {ChannelValue} value - The channel value. + * @returns {LocalValue} - The created LocalValue object. + */ static createChannelValue(value) { return new LocalValue(NonPrimitiveType.CHANNEL, value) } @@ -109,6 +196,11 @@ class LocalValue { } } +/** + * Represents a remote value. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteValue. + * @class + */ class RemoteValue { constructor(remoteValue) { this.type = null @@ -159,9 +251,19 @@ class RemoteValue { } } +/** + * Represents a reference value in the protocol. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteReference. + */ class ReferenceValue { #handle #sharedId + + /** + * Constructs a new ReferenceValue object. + * @param {string} handle - The handle value. + * @param {string} sharedId - The shared ID value. + */ constructor(handle, sharedId) { if (handle === RemoteReferenceType.HANDLE) { this.#handle = sharedId @@ -187,14 +289,34 @@ class ReferenceValue { } } +/** + * Represents a regular expression value. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue. + */ class RegExpValue { + /** + * Constructs a new RegExpValue object. + * @param {string} pattern - The pattern of the regular expression. + * @param {string|null} [flags=null] - The flags of the regular expression. + */ constructor(pattern, flags = null) { this.pattern = pattern this.flags = flags } } +/** + * Represents serialization options. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-SerializationOptions. + */ class SerializationOptions { + /** + * Constructs a new instance of SerializationOptions. + * @param {number} [maxDomDepth=0] - The maximum depth to serialize the DOM. + * @param {number|null} [maxObjectDepth=null] - The maximum depth to serialize objects. + * @param {'none'|'open'|'all'} [includeShadowTree='none'] - The inclusion level of the shadow tree. + * @throws {Error} If the `includeShadowTree` value is not one of 'none', 'open', or 'all'. + */ constructor(maxDomDepth = 0, maxObjectDepth = null, includeShadowTree = 'none') { this._maxDomDepth = maxDomDepth this._maxObjectDepth = maxObjectDepth @@ -206,6 +328,11 @@ class SerializationOptions { } } +/** + * Represents a channel value. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-ChannelValue. + * @class + */ class ChannelValue { constructor(channel, options = undefined, resultOwnership = undefined) { this.channel = channel diff --git a/javascript/node/selenium-webdriver/bidi/provideResponseParameters.js b/javascript/node/selenium-webdriver/bidi/provideResponseParameters.js index 08348379a239cf..9dc4d4226e5b24 100644 --- a/javascript/node/selenium-webdriver/bidi/provideResponseParameters.js +++ b/javascript/node/selenium-webdriver/bidi/provideResponseParameters.js @@ -17,6 +17,11 @@ const { BytesValue, Header } = require('./networkTypes') +/** + * Represents parameters for providingResponse command. + * Described in https://w3c.github.io/webdriver-bidi/#command-network-provideResponse. + * @class + */ class ProvideResponseParameters { #map = new Map() @@ -24,6 +29,13 @@ class ProvideResponseParameters { this.#map.set('request', request) } + /** + * Sets the body value for the response parameters. + * + * @param {BytesValue} value - The value to set as the body. Must be an instance of BytesValue. + * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining. + * @throws {Error} - Throws an error if the value is not an instance of BytesValue. + */ body(value) { if (!(value instanceof BytesValue)) { throw new Error(`Value must be an instance of BytesValue. Received: ${typeof value} with value: ${value}`) @@ -32,6 +44,13 @@ class ProvideResponseParameters { return this } + /** + * Sets the cookie headers for the response. + * + * @param {Header[]} cookieHeaders - An array of cookie headers. + * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining. + * @throws {Error} - Throws an error if a cookie header is not an instance of Header. + */ cookies(cookieHeaders) { const cookies = [] cookieHeaders.forEach((header) => { @@ -45,6 +64,13 @@ class ProvideResponseParameters { return this } + /** + * Sets the headers for the response. + * + * @param {Header[]} headers - The headers to be set. + * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining. + * @throws {Error} - If the provided header is not an instance of Header. + */ headers(headers) { const headerList = [] headers.forEach((header) => { @@ -58,6 +84,13 @@ class ProvideResponseParameters { return this } + /** + * Sets the reason phrase for the response. + * + * @param {string} reasonPhrase - The reason phrase to set. + * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining. + * @throws {Error} - If the reason phrase is not a string. + */ reasonPhrase(reasonPhrase) { if (typeof reasonPhrase !== 'string') { throw new Error(`Reason phrase must be a string. Received: '${reasonPhrase})'`) @@ -66,6 +99,13 @@ class ProvideResponseParameters { return this } + /** + * Sets the status code for the response. + * + * @param {number} statusCode - The status code to set. + * @returns {ProvideResponseParameters} - Returns the ProvideResponseParameters object for chaining. + * @throws {Error} - If the status code is not an integer. + */ statusCode(statusCode) { if (!Number.isInteger(statusCode)) { throw new Error(`Status must be an integer. Received:'${statusCode}'`) diff --git a/javascript/node/selenium-webdriver/bidi/realmInfo.js b/javascript/node/selenium-webdriver/bidi/realmInfo.js index 98423a26dc37d4..0c02a5e729c4ab 100644 --- a/javascript/node/selenium-webdriver/bidi/realmInfo.js +++ b/javascript/node/selenium-webdriver/bidi/realmInfo.js @@ -15,6 +15,11 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents the types of realms. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-RealmType. + * @enum + */ const RealmType = { AUDIO_WORKLET: 'audio-worklet', DEDICATED_WORKER: 'dedicated-worker', @@ -34,7 +39,17 @@ const RealmType = { }, } +/** + * Represents information about a realm. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-RealmInfo. + */ class RealmInfo { + /** + * Constructs a new RealmInfo object. + * @param {string} realmId - The ID of the realm. + * @param {string} origin - The origin of the realm. + * @param {string} realmType - The type of the realm. + */ constructor(realmId, origin, realmType) { this.realmId = realmId this.origin = origin @@ -77,7 +92,19 @@ class RealmInfo { } } +/** + * Represents information about a window realm. + * @extends RealmInfo + */ class WindowRealmInfo extends RealmInfo { + /** + * Constructs a new instance of the WindowRealmInfo class. + * @param {string} realmId - The ID of the realm. + * @param {string} origin - The origin of the realm. + * @param {string} realmType - The type of the realm. + * @param {string} browsingContext - The browsing context of the realm. + * @param {string|null} sandbox - The sandbox of the realm (optional). + */ constructor(realmId, origin, realmType, browsingContext, sandbox = null) { super(realmId, origin, realmType) this.browsingContext = browsingContext diff --git a/javascript/node/selenium-webdriver/bidi/resultOwnership.js b/javascript/node/selenium-webdriver/bidi/resultOwnership.js index 42758eccd7fcec..df5d845d85359a 100644 --- a/javascript/node/selenium-webdriver/bidi/resultOwnership.js +++ b/javascript/node/selenium-webdriver/bidi/resultOwnership.js @@ -15,6 +15,10 @@ // specific language governing permissions and limitations // under the License. +/** + * Enum representing the ownership types. + * @enum {string} + */ const ResultOwnership = { ROOT: 'root', NONE: 'none', diff --git a/javascript/node/selenium-webdriver/bidi/scriptManager.js b/javascript/node/selenium-webdriver/bidi/scriptManager.js index 3fffc5a872ebef..11e4181bde5a49 100644 --- a/javascript/node/selenium-webdriver/bidi/scriptManager.js +++ b/javascript/node/selenium-webdriver/bidi/scriptManager.js @@ -23,10 +23,16 @@ const { } = require('./evaluateResult') const { Message } = require('./scriptTypes') const { RealmInfo, RealmType, WindowRealmInfo } = require('./realmInfo') -const { RemoteValue } = require('./protocolValue') +const { RemoteValue, LocalValue } = require('./protocolValue') const { Source } = require('./scriptTypes') const { WebDriverError } = require('../lib/error') +const { ResultOwnership } = require('./resultOwnership') +/** + * Represents class to run events and commands of Script module. + * Described in https://w3c.github.io/webdriver-bidi/#module-script. + * @class + */ class ScriptManager { constructor(driver) { this._driver = driver @@ -41,6 +47,13 @@ class ScriptManager { this._browsingContextIds = browsingContextIds } + /** + * Disowns the handles in the specified realm. + * + * @param {string} realmId - The ID of the realm. + * @param {string[]} handles - The handles to disown to allow garbage collection. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async disownRealmScript(realmId, handles) { const params = { method: 'script.disown', @@ -55,6 +68,13 @@ class ScriptManager { await this.bidi.send(params) } + /** + * Disowns the handles in the specified browsing context. + * @param {string} browsingContextId - The ID of the browsing context. + * @param {string[]} handles - The handles to disown to allow garbage collection. + * @param {String|null} [sandbox=null] - The sandbox name. + * @returns {Promise} - A promise that resolves when the command is sent. + */ async disownBrowsingContextScript(browsingContextId, handles, sandbox = null) { const params = { method: 'script.disown', @@ -73,6 +93,17 @@ class ScriptManager { await this.bidi.send(params) } + /** + * Calls a function in the specified realm. + * + * @param {string} realmId - The ID of the realm. + * @param {string} functionDeclaration - The function to call. + * @param {boolean} awaitPromise - Whether to await the promise returned by the function. + * @param {LocalValue[]} [argumentValueList|null] - The list of argument values to pass to the function. + * @param {Object} [thisParameter|null] - The value of 'this' parameter for the function. + * @param {ResultOwnership} [resultOwnership|null] - The ownership of the result. + * @returns {Promise} - A promise that resolves to the evaluation result or exception. + */ async callFunctionInRealm( realmId, functionDeclaration, @@ -101,6 +132,17 @@ class ScriptManager { return this.createEvaluateResult(response) } + /** + * Calls a function in the specified browsing context. + * + * @param {string} realmId - The ID of the browsing context. + * @param {string} functionDeclaration - The function to call. + * @param {boolean} awaitPromise - Whether to await the promise returned by the function. + * @param {LocalValue[]} [argumentValueList|null] - The list of argument values to pass to the function. + * @param {Object} [thisParameter|null] - The value of 'this' parameter for the function. + * @param {ResultOwnership} [resultOwnership|null] - The ownership of the result. + * @returns {Promise} - A promise that resolves to the evaluation result or exception. + */ async callFunctionInBrowsingContext( browsingContextId, functionDeclaration, @@ -129,6 +171,15 @@ class ScriptManager { return this.createEvaluateResult(response) } + /** + * Evaluates a function in the specified realm. + * + * @param {string} realmId - The ID of the realm. + * @param {string} expression - The expression to function to evaluate. + * @param {boolean} awaitPromise - Whether to await the promise. + * @param {ResultOwnership|null} resultOwnership - The ownership of the result. + * @returns {Promise} - A promise that resolves to the evaluation result or exception. + */ async evaluateFunctionInRealm(realmId, expression, awaitPromise, resultOwnership = null) { const params = this.getEvaluateParams('realm', realmId, null, expression, awaitPromise, resultOwnership) @@ -141,6 +192,15 @@ class ScriptManager { return this.createEvaluateResult(response) } + /** + * Evaluates a function in the browsing context. + * + * @param {string} realmId - The ID of the browsing context. + * @param {string} expression - The expression to function to evaluate. + * @param {boolean} awaitPromise - Whether to await the promise. + * @param {ResultOwnership|null} resultOwnership - The ownership of the result. + * @returns {Promise} - A promise that resolves to the evaluation result or exception. + */ async evaluateFunctionInBrowsingContext( browsingContextId, expression, @@ -166,6 +226,14 @@ class ScriptManager { return this.createEvaluateResult(response) } + /** + * Adds a preload script. + * + * @param {string} functionDeclaration - The declaration of the function to be added as a preload script. + * @param {LocalValue[]} [argumentValueList=[]] - The list of argument values to be passed to the preload script function. + * @param {string} [sandbox|null] - The sandbox object to be used for the preload script. + * @returns {Promise} - A promise that resolves to the added preload script ID. + */ async addPreloadScript(functionDeclaration, argumentValueList = [], sandbox = null) { const params = { functionDeclaration: functionDeclaration, @@ -190,6 +258,13 @@ class ScriptManager { return response.result.script } + /** + * Removes a preload script. + * + * @param {string} script - The ID for the script to be removed. + * @returns {Promise} - A promise that resolves with the result of the removal. + * @throws {WebDriverError} - If an error occurs during the removal process. + */ async removePreloadScript(script) { const params = { script: script } const command = { @@ -290,6 +365,10 @@ class ScriptManager { return realmsList } + /** + * Retrieves all realms. + * @returns {Promise} - A promise that resolves to an array of RealmInfo objects. + */ async getAllRealms() { const command = { method: 'script.getRealms', @@ -299,6 +378,12 @@ class ScriptManager { return this.realmInfoMapper(response.result.realms) } + /** + * Retrieves the realms by type. + * + * @param {Type} type - The type of realms to retrieve. + * @returns {Promise} - A promise that resolves to an array of RealmInfo objects. + */ async getRealmsByType(type) { const command = { method: 'script.getRealms', @@ -308,6 +393,12 @@ class ScriptManager { return this.realmInfoMapper(response.result.realms) } + /** + * Retrieves the realms in the specified browsing context. + * + * @param {string} browsingContext - The browsing context ID. + * @returns {Promise} - A promise that resolves to an array of RealmInfo objects. + */ async getRealmsInBrowsingContext(browsingContext) { const command = { method: 'script.getRealms', @@ -317,6 +408,13 @@ class ScriptManager { return this.realmInfoMapper(response.result.realms) } + /** + * Retrieves the realms in a browsing context based on the specified type. + * + * @param {string} browsingContext - The browsing context ID. + * @param {string} type - The type of realms to retrieve. + * @returns {Promise} - A promise that resolves to an array of RealmInfo objects. + */ async getRealmsInBrowsingContextByType(browsingContext, type) { const command = { method: 'script.getRealms', @@ -326,14 +424,32 @@ class ScriptManager { return this.realmInfoMapper(response.result.realms) } + /** + * Subscribes to the 'script.message' event and handles the callback function when a message is received. + * + * @param {Function} callback - The callback function to be executed when a message is received. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async onMessage(callback) { await this.subscribeAndHandleEvent('script.message', callback) } + /** + * Subscribes to the 'script.realmCreated' event and handles it with the provided callback. + * + * @param {Function} callback - The callback function to handle the 'script.realmCreated' event. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async onRealmCreated(callback) { await this.subscribeAndHandleEvent('script.realmCreated', callback) } + /** + * Subscribes to the 'script.realmDestroyed' event and handles it with the provided callback function. + * + * @param {Function} callback - The callback function to be executed when the 'script.realmDestroyed' event occurs. + * @returns {Promise} - A promise that resolves when the subscription is successful. + */ async onRealmDestroyed(callback) { await this.subscribeAndHandleEvent('script.realmDestroyed', callback) } diff --git a/javascript/node/selenium-webdriver/bidi/scriptTypes.js b/javascript/node/selenium-webdriver/bidi/scriptTypes.js index faa14a5b076427..ee2b9ce9827c21 100644 --- a/javascript/node/selenium-webdriver/bidi/scriptTypes.js +++ b/javascript/node/selenium-webdriver/bidi/scriptTypes.js @@ -15,26 +15,56 @@ // specific language governing permissions and limitations // under the License. +const { RemoteValue } = require('./protocolValue') + +/** + * Represents a message received through a channel. + * Described in https://w3c.github.io/webdriver-bidi/#event-script-message. + * @class + */ class Message { + /** + * Creates a new Message instance. + * @param {string} channel - The channel through which the message is received. + * @param {RemoteValue} data - The data contained in the message. + * @param {Source} source - The source of the message. + */ constructor(channel, data, source) { this._channel = channel this._data = data this._source = source } + /** + * Gets the channel through which the message is received. + * @returns {string} The channel. + */ get channel() { return this._channel } + /** + * Gets the data contained in the message. + * @returns {RemoteValue} The data. + */ get data() { return this._data } + /** + * Gets the source of the message. + * @returns {Source} The source. + */ get source() { return this._source } } +/** + * Represents a source object. + * Described in https://w3c.github.io/webdriver-bidi/#type-script-Source. + * @class + */ class Source { constructor(source) { this._browsingContextId = null @@ -46,10 +76,18 @@ class Source { } } + /** + * Get the browsing context ID. + * @returns {string|null} The browsing context ID. + */ get browsingContextId() { return this._browsingContextId } + /** + * Get the realm ID. + * @returns {string} The realm ID. + */ get realmId() { return this._realmId } diff --git a/javascript/node/selenium-webdriver/bidi/storage.js b/javascript/node/selenium-webdriver/bidi/storage.js index a08547bf205eaf..86eba93eef656a 100644 --- a/javascript/node/selenium-webdriver/bidi/storage.js +++ b/javascript/node/selenium-webdriver/bidi/storage.js @@ -21,6 +21,11 @@ const { PartitionKey } = require('./partitionKey') const { PartialCookie } = require('./partialCookie') const { Cookie, BytesValue } = require('./networkTypes') +/** + * Represents commands of Storage module. + * Described in https://w3c.github.io/webdriver-bidi/#module-storage. + * @class + */ class Storage { constructor(driver) { this._driver = driver @@ -34,6 +39,15 @@ class Storage { this.bidi = await this._driver.getBidi() } + /** + * Retrieves cookies based on the provided filter and partition. + * + * @param {CookieFilter} [filter] - The filter to apply to the cookies. + * @param {(BrowsingContextPartitionDescriptor|StorageKeyPartitionDescriptor)} [partition] - The partition to retrieve cookies from. + * @returns {Promise<{ cookies: Cookie[], partitionKey?: PartitionKey }>} - A promise that resolves to an object containing the retrieved cookies and an optional partition key. + * @throws {Error} If the filter parameter is provided but is not an instance of CookieFilter. + * @throws {Error} If the partition parameter is provided but is not an instance of BrowsingContextPartitionDescriptor or StorageKeyPartitionDescriptor. + */ async getCookies(filter = undefined, partition = undefined) { if (filter !== undefined && !(filter instanceof CookieFilter)) { throw new Error(`Params must be an instance of CookieFilter. Received:'${filter}'`) @@ -89,6 +103,14 @@ class Storage { } } + /** + * Sets a cookie using the provided cookie object and partition. + * + * @param {PartialCookie} cookie - The cookie object to set. + * @param {(BrowsingContextPartitionDescriptor|StorageKeyPartitionDescriptor)} [partition] - The partition to use for the cookie. + * @returns {PartitionKey} The partition key of the set cookie. + * @throws {Error} If the cookie parameter is not an instance of PartialCookie or if the partition parameter is not an instance of PartitionDescriptor. + */ async setCookie(cookie, partition = undefined) { if (!(cookie instanceof PartialCookie)) { throw new Error(`Params must be an instance of PartialCookie. Received:'${cookie}'`) @@ -125,6 +147,14 @@ class Storage { } } + /** + * Deletes cookies based on the provided filter and partition. + * + * @param {CookieFilter} [cookieFilter] - The filter to apply to the cookies. Must be an instance of CookieFilter. + * @param {(BrowsingContextPartitionDescriptor|StorageKeyPartitionDescriptor)} [partition] - The partition to delete cookies from. Must be an instance of either BrowsingContextPartitionDescriptor or StorageKeyPartitionDescriptor. + * @returns {PartitionKey} - The partition key of the deleted cookies, if available. + * @throws {Error} - If the provided parameters are not of the correct type. + */ async deleteCookies(cookieFilter = undefined, partition = undefined) { if (cookieFilter !== undefined && !(cookieFilter instanceof CookieFilter)) { throw new Error(`Params must be an instance of CookieFilter. Received:'${cookieFilter}'`) diff --git a/javascript/node/selenium-webdriver/bidi/urlPattern.js b/javascript/node/selenium-webdriver/bidi/urlPattern.js index 8b69cee0923f43..fdff80015ccab0 100644 --- a/javascript/node/selenium-webdriver/bidi/urlPattern.js +++ b/javascript/node/selenium-webdriver/bidi/urlPattern.js @@ -15,19 +15,42 @@ // specific language governing permissions and limitations // under the License. +/** + * Represents a URL pattern to intercept. + * Described in network.UrlPatternPattern https://w3c.github.io/webdriver-bidi/#type-network-UrlPattern + */ class UrlPattern { #map = new Map() + /** + * Sets the protocol for the URL pattern. + * + * @param {string} protocol - The protocol to set. + * @returns {UrlPattern} - Returns the updated instance of the URL pattern for chaining. + */ protocol(protocol) { this.#map.set('protocol', protocol) return this } + /** + * Sets the hostname for the URL pattern. + * + * @param {string} hostname - The hostname to set. + * @returns {UrlPattern} - Returns the updated instance of the URL pattern for chaining. + */ hostname(hostname) { this.#map.set('hostname', hostname) return this } + /** + * Sets the port for the URL pattern. + * + * @param {number} port - The port number to set. + * @returns {UrlPattern} - Returns the updated instance of the URL pattern for chaining. + * @throws {Error} - Throws an error if the port is not a number. + */ port(port) { if (typeof port === 'number') { this.#map.set('port', port.toString()) @@ -37,11 +60,23 @@ class UrlPattern { return this } + /** + * Sets the pathname for the URL pattern. + * + * @param {string} pathname - The pathname to set. + * @returns {UrlPattern} - Returns the updated instance of the URL pattern for chaining. + */ pathname(pathname) { this.#map.set('pathname', pathname) return this } + /** + * Sets the search parameter in the URL pattern. + * + * @param {string} search - The search parameter to be set. + * @returns {UrlPattern} - Returns the updated instance of the URL pattern for chaining. + */ search(search) { this.#map.set('search', search) return this