From b622defe0b8d2f7b4f9194e4fac3359e3485138e Mon Sep 17 00:00:00 2001 From: touero Date: Thu, 27 Feb 2025 11:57:48 +0800 Subject: [PATCH 1/5] fix(py): Add some test for listeners --- .../python/tests/support/test_listener.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/examples/python/tests/support/test_listener.py b/examples/python/tests/support/test_listener.py index 53b695b6fc83..7ee76d4efb05 100644 --- a/examples/python/tests/support/test_listener.py +++ b/examples/python/tests/support/test_listener.py @@ -1,2 +1,25 @@ +import time from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener +TEST_URL = "https://www.selenium.dev/selenium/web/clicks.html" + +class MyListener(AbstractEventListener): + def before_click(self, element, driver): + print(f"Before click: {element.text}") + assert element.text == "I'm a normal link" + + def after_navigate_to(self, url, driver): + print(f"After navigating to: {url}") + assert url == TEST_URL + + +def test_listener(): + driver = webdriver.Chrome() + event_driver = EventFiringWebDriver(driver, MyListener()) + event_driver.get(TEST_URL) + time.sleep(2) + element = event_driver.find_element(By.ID, "normal") + element.click() + event_driver.quit() From 412eaaafef2d3c89d748f6b2fa4c31a1547f074c Mon Sep 17 00:00:00 2001 From: touero Date: Thu, 27 Feb 2025 14:23:55 +0800 Subject: [PATCH 2/5] docs(py-listeners): update listeners docs --- .../documentation/webdriver/support_features/listeners.en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md index cfecbd7cb65f..5bae8c495c97 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md @@ -14,7 +14,7 @@ These allow you to execute custom actions in every time specific Selenium comman {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} -{{< badge-code >}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L25" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} From eb72b9c24e46ff8f33747f2970d4844588486178 Mon Sep 17 00:00:00 2001 From: touero Date: Fri, 28 Feb 2025 14:05:24 +0800 Subject: [PATCH 3/5] fix(py): add example for python selenium listener --- .../python/tests/support/test_listener.py | 161 ++++++++++++++++-- 1 file changed, 147 insertions(+), 14 deletions(-) diff --git a/examples/python/tests/support/test_listener.py b/examples/python/tests/support/test_listener.py index 7ee76d4efb05..4e5813b3eb30 100644 --- a/examples/python/tests/support/test_listener.py +++ b/examples/python/tests/support/test_listener.py @@ -1,25 +1,158 @@ -import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener -TEST_URL = "https://www.selenium.dev/selenium/web/clicks.html" class MyListener(AbstractEventListener): - def before_click(self, element, driver): - print(f"Before click: {element.text}") - assert element.text == "I'm a normal link" + def __init__(self): + self.events = [] - def after_navigate_to(self, url, driver): - print(f"After navigating to: {url}") - assert url == TEST_URL + def before_navigate_to(self, url: str, driver) -> None: + print(f"before_navigate_to: {url}") + self.events.append(f"before_navigate_to") + def after_navigate_to(self, url: str, driver) -> None: + print(f"after_navigate_to: {url}") + self.events.append(f"after_navigate_to") -def test_listener(): + def before_navigate_back(self, driver) -> None: + print("before_navigate_back") + self.events.append("before_navigate_back") + + def after_navigate_back(self, driver) -> None: + print("after_navigate_back") + self.events.append("after_navigate_back") + + def before_navigate_forward(self, driver) -> None: + print("before_navigate_forward") + self.events.append("before_navigate_forward") + + def after_navigate_forward(self, driver) -> None: + print("after_navigate_forward") + self.events.append("after_navigate_forward") + + def before_close(self, driver) -> None: + print("before_close") + self.events.append("before_close") + + def after_close(self, driver) -> None: + print("after_close") + self.events.append("after_close") + + def before_quit(self, driver) -> None: + print("before_quit") + self.events.append("before_quit") + + def after_quit(self, driver) -> None: + print("after_quit") + self.events.append("after_quit") + + def before_find(self, by, value, driver) -> None: + print("before_find") + self.events.append("before_find") + + def after_find(self, by, value, driver) -> None: + print("after_find") + self.events.append("after_find") + + def before_click(self, element, driver) -> None: + print("before_click") + self.events.append("before_click") + + def after_click(self, element, driver) -> None: + print("after_click") + self.events.append("after_click") + + def before_change_value_of(self, element, driver) -> None: + print("before_change_value") + self.events.append("before_change_value") + + def after_change_value_of(self, element, driver) -> None: + print("after_change_value") + self.events.append("after_change_value") + + def before_execute_script(self, script, driver) -> None: + print("before_execute_script") + self.events.append("before_execute_script") + + def after_execute_script(self, script, driver) -> None: + print("after_execute_script") + self.events.append("after_execute_script") + + def on_exception(self, exception, driver) -> None: + print("on_exception") + self.events.append("on_exception") + +def test_navigate_and_quit(): driver = webdriver.Chrome() - event_driver = EventFiringWebDriver(driver, MyListener()) - event_driver.get(TEST_URL) - time.sleep(2) - element = event_driver.find_element(By.ID, "normal") - element.click() + listener = MyListener() + event_driver = EventFiringWebDriver(driver, listener) + event_driver.get("https://www.selenium.dev/selenium/web/") + event_driver.get("https://www.selenium.dev/selenium/web/clicks.html") + event_driver.back() + event_driver.forward() event_driver.quit() + print(listener.events) + + assert "before_navigate_to" in listener.events + assert "after_navigate_to" in listener.events + assert "before_navigate_back" in listener.events + assert "after_navigate_back" in listener.events + assert "before_navigate_forward" in listener.events + assert "after_navigate_forward" in listener.events + assert "before_quit" in listener.events + assert "after_quit" in listener.events + +def test_find_and_click_and_close(): + driver = webdriver.Chrome() + listener = MyListener() + event_driver = EventFiringWebDriver(driver, listener) + event_driver.get("https://www.selenium.dev/selenium/web/clicks.html") + element = event_driver.find_element(By.ID, "new-window") + + assert 'before_find' in listener.events + assert 'after_find' in listener.events + + element.click() + + assert 'before_click' in listener.events + assert 'after_click' in listener.events + + event_driver.switch_to.window(event_driver.window_handles[-1]) + event_driver.close() + + assert 'before_close' in listener.events + + event_driver.switch_to.window(event_driver.window_handles[0]) + print(listener.events) + +def test_change_value(): + driver = webdriver.Chrome() + listener = MyListener() + event_driver = EventFiringWebDriver(driver, listener) + event_driver.get("https://www.selenium.dev/selenium/web/inputs.html") + element = event_driver.find_element(By.NAME, "no_type") + print(listener.events) + element.clear() + + assert 'before_change_value' in listener.events + assert 'after_change_value' in listener.events + +def test_execute_script_and_exception(): + driver = webdriver.Chrome() + listener = MyListener() + event_driver = EventFiringWebDriver(driver, listener) + urls = ["https://www.selenium.dev/selenium/web/", + "https://www.selenium.dev/selenium/web/inputs.html"] + for url in urls: + event_driver.get(url) + try: + element = event_driver.find_element(By.NAME, "no_type") + print(listener.events) + event_driver.execute_script("arguments[0].value = 'test'", element) + except Exception as e: + print(f"Exception: {e}") + continue + + assert 'before_execute_script' in listener.events + assert 'after_execute_script' in listener.events From 3384cd2ccd26ed3db04e293d3311ba6f5bf71722 Mon Sep 17 00:00:00 2001 From: touero Date: Fri, 28 Feb 2025 15:13:04 +0800 Subject: [PATCH 4/5] docs(py): update webdriver feature listener docs --- .../support_features/listeners.en.md | 36 +++++++++++++++++-- .../support_features/listeners.zh-cn.md | 30 ++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md index 5bae8c495c97..acfcd664f319 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md @@ -7,14 +7,45 @@ aliases: [ ] --- -These allow you to execute custom actions in every time specific Selenium commands are sent +These allow you to execute custom actions in every time specific Selenium commands are sent. + + +## Define + +A custom Listener needs to inherit from AbstractEventListener in Selenium and override the methods in AbstractEventListener. + Here’s a simple example to print and log events: + +{{< tabpane text=true >}} +{{< tab header="Java" >}} +{{< badge-code >}} +{{< /tab >}} +{{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py" >}} +{{% /tab %}} +{{< tab header="CSharp" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="Ruby" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="JavaScript" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="Kotlin" >}} +{{< badge-code >}} +{{< /tab >}} +{{< /tabpane >}} + +## Usage + +Create an event listener driver through EventFiringWebDriver: {{< tabpane text=true >}} {{< tab header="Java" >}} {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} -{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L25" >}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L87-L96" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} @@ -29,3 +60,4 @@ These allow you to execute custom actions in every time specific Selenium comman {{< badge-code >}} {{< /tab >}} {{< /tabpane >}} + diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md index 015b9e9afb76..88172245bfe7 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md @@ -9,12 +9,42 @@ aliases: [ 允许您在每次发送特定 Selenium 命令时执行自定义操作 +## 定义 + +自定义的Listener需要继承selenium中的AbstractEventListener同时重写AbstractEventListener中的方法, +有一个简单打印和记录事件的例子: + {{< tabpane text=true >}} {{< tab header="Java" >}} {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L33" >}} +{{% /tab %}} +{{< tab header="CSharp" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="Ruby" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="JavaScript" >}} {{< badge-code >}} +{{< /tab >}} +{{< tab header="Kotlin" >}} +{{< badge-code >}} +{{< /tab >}} +{{< /tabpane >}} + +## 使用 + +通过EventFiringWebDriver创建监听事件driver: + +{{< tabpane text=true >}} +{{< tab header="Java" >}} +{{< badge-code >}} +{{< /tab >}} +{{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L87-L96" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} From 61431b976af53e439f0cec5a4dec4748e2eb103c Mon Sep 17 00:00:00 2001 From: touero Date: Fri, 28 Feb 2025 15:36:56 +0800 Subject: [PATCH 5/5] docs(tra): translate to other languages --- .../support_features/listeners.en.md | 6 +-- .../support_features/listeners.ja.md | 40 +++++++++++++++++-- .../support_features/listeners.pt-br.md | 40 +++++++++++++++++-- .../support_features/listeners.zh-cn.md | 2 +- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md index acfcd664f319..6619c864d34b 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.en.md @@ -12,15 +12,15 @@ These allow you to execute custom actions in every time specific Selenium comman ## Define -A custom Listener needs to inherit from AbstractEventListener in Selenium and override the methods in AbstractEventListener. - Here’s a simple example to print and log events: +A custom Listener needs to inherit from AbstractEventListener in Selenium and override the methods in AbstractEventListener. +Here’s a simple example to print and log events: {{< tabpane text=true >}} {{< tab header="Java" >}} {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} -{{< gh-codeblock path="examples/python/tests/support/test_listener.py" >}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L33" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.ja.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.ja.md index 09714561af9a..34db4e3093e5 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.ja.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.ja.md @@ -1,20 +1,51 @@ --- -title: "Command Listeners" -linkTitle: "Listeners" +title: "コマンドリスナー" +linkTitle: "リスナー" weight: 2 aliases: [ - "/ja/documentation/webdriver/drivers/listeners", + "/documentation/webdriver/drivers/listeners", ] --- -These allow you to execute custom actions in every time specific Selenium commands are sent +これにより、特定のSeleniumコマンドが送信されるたびにカスタムアクションを実行することができます。 + + +## 定義 + +カスタムリスナーは、SeleniumのAbstractEventListenerを継承し、AbstractEventListenerのメソッドをオーバーライドする必要があります。 +イベントを印刷してログに記録するための簡単な例を示します: {{< tabpane text=true >}} {{< tab header="Java" >}} {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L33" >}} +{{% /tab %}} +{{< tab header="CSharp" >}} {{< badge-code >}} +{{< /tab >}} +{{< tab header="Ruby" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="JavaScript" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="Kotlin" >}} +{{< badge-code >}} +{{< /tab >}} +{{< /tabpane >}} + +## 使用(しよう) + +EventFiringWebDriverを使ってイベントリスナードライバーを作成する: + +{{< tabpane text=true >}} +{{< tab header="Java" >}} +{{< badge-code >}} +{{< /tab >}} +{{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L87-L96" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} @@ -29,3 +60,4 @@ These allow you to execute custom actions in every time specific Selenium comman {{< badge-code >}} {{< /tab >}} {{< /tabpane >}} + diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.pt-br.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.pt-br.md index d23c1655dc57..cae0cc570fe4 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.pt-br.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.pt-br.md @@ -1,20 +1,51 @@ --- -title: "Command Listeners" -linkTitle: "Listeners" +title: "Ouvintes de Comando" +linkTitle: "Ouvintes" weight: 2 aliases: [ - "/pt-br/documentation/webdriver/drivers/listeners", + "/documentation/webdriver/drivers/listeners", ] --- -These allow you to execute custom actions in every time specific Selenium commands are sent +isso permite que você execute ações personalizadas sempre que comandos específicos do Selenium são enviados. + + +## Definir + +Um Listener personalizado precisa herdar de AbstractEventListener no Selenium e sobrescrever os métodos em AbstractEventListener. +Aqui está um exemplo simples para imprimir e registrar eventos: {{< tabpane text=true >}} {{< tab header="Java" >}} {{< badge-code >}} {{< /tab >}} {{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L1-L33" >}} +{{% /tab %}} +{{< tab header="CSharp" >}} {{< badge-code >}} +{{< /tab >}} +{{< tab header="Ruby" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="JavaScript" >}} +{{< badge-code >}} +{{< /tab >}} +{{< tab header="Kotlin" >}} +{{< badge-code >}} +{{< /tab >}} +{{< /tabpane >}} + +## Uso + +Crie um driver de ouvinte de eventos através do EventFiringWebDriver: + +{{< tabpane text=true >}} +{{< tab header="Java" >}} +{{< badge-code >}} +{{< /tab >}} +{{% tab header="Python" %}} +{{< gh-codeblock path="examples/python/tests/support/test_listener.py#L87-L96" >}} {{% /tab %}} {{< tab header="CSharp" >}} {{< badge-code >}} @@ -29,3 +60,4 @@ These allow you to execute custom actions in every time specific Selenium comman {{< badge-code >}} {{< /tab >}} {{< /tabpane >}} + diff --git a/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md b/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md index 88172245bfe7..e43b228b9359 100644 --- a/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md +++ b/website_and_docs/content/documentation/webdriver/support_features/listeners.zh-cn.md @@ -11,7 +11,7 @@ aliases: [ ## 定义 -自定义的Listener需要继承selenium中的AbstractEventListener同时重写AbstractEventListener中的方法, +自定义的Listener需要继承selenium中的AbstractEventListener同时重写AbstractEventListener中的方法. 有一个简单打印和记录事件的例子: {{< tabpane text=true >}}