From 2dde5494f837d9d29e2ef03de4d9b208ba1bcb76 Mon Sep 17 00:00:00 2001 From: bashang Date: Tue, 9 Jan 2024 23:06:59 +0800 Subject: [PATCH 1/6] Add mark and measure function --- pylenium/performance.py | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pylenium/performance.py b/pylenium/performance.py index 95fda65..54781ad 100644 --- a/pylenium/performance.py +++ b/pylenium/performance.py @@ -109,6 +109,48 @@ def get_resources(self): except TimeoutException: return None # because there were no Resources captured for the current web page + def mark(self, name) -> str: + js = 'return window.performance.mark("{}")[0];'.format(name) + start_mark = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMark not generated yet") + print(start_mark) + return PerformanceMark(**start_mark).name + + def measure(self, start_name) -> float: + end_name = self.mark("end") + js = 'return window.performance.measure("{}", "{}", "{}")[0];'.format("measure", start_name, end_name) + measures = self._wait().until(lambda driver: driver.execute_script(js),"PerformanceMeasure not generated yet") + print(measures) + + +class PerformanceMeasure(BaseModel): + """The PerformanceNavigationTiming Representation. + + Metrics regarding the browser's document navigation events + + References: + https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMeasure + """ + + detail: str = Field(alias="detail") + name: str = Field(alias="name") + entry_type: str = Field(alias="entryType") + start_time: float = Field(alias="startTime") + duration: float = Field(alias="duration") + +class PerformanceMark(BaseModel): + """The PerformanceMark Representation. + + Metrics regarding the browser's document navigation events + + References: + https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMark + """ + + detail: str = Field(alias="detail") + name: str = Field(alias="name") + entry_type: str = Field(alias="entryType") + start_time: float = Field(alias="startTime") + duration: float = Field(alias="duration") class NavigationTiming(BaseModel): """The PerformanceNavigationTiming Representation. From c3a4813277d3fd6130d23809e62007ffb74ef7e7 Mon Sep 17 00:00:00 2001 From: bashang Date: Tue, 9 Jan 2024 23:07:20 +0800 Subject: [PATCH 2/6] add test for mark and measure --- tests/test_flows.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_flows.py b/tests/test_flows.py index a7a3462..9a7472f 100644 --- a/tests/test_flows.py +++ b/tests/test_flows.py @@ -26,3 +26,13 @@ def test_add_to_cart_xpath(self, sauce: Pylenium): button.click() sauce.getx("//a[@class='shopping_cart_link']").click() assert sauce.findx("//*[@class='cart_item']").should().have_length(6) + + def test_add_to_cart_xpath(sauce: Pylenium): + """Add 6 different items to the cart. There should be 6 items in the cart.""" + start_name = sauce.performance.mark("before") + for button in sauce.findx("//*[contains(@id, 'add-to-cart')]"): + button.click() + sauce.getx("//a[@class='shopping_cart_link']").click() + assert sauce.findx("//*[@class='cart_item']").should().have_length(6) + time = sauce.performance.measure("measure", start_name) + assert time < 5, "Took longer than 5 seconds to add item to cart using xpath" From 624cd39d056027ac96b05604280919cb3fb16319 Mon Sep 17 00:00:00 2001 From: bashang Date: Wed, 10 Jan 2024 01:29:17 +0800 Subject: [PATCH 3/6] - fix mark() and measure() - update test flow --- pylenium/performance.py | 26 ++++++++++++-------------- tests/test_flows.py | 8 ++++---- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/pylenium/performance.py b/pylenium/performance.py index 54781ad..820d242 100644 --- a/pylenium/performance.py +++ b/pylenium/performance.py @@ -109,21 +109,19 @@ def get_resources(self): except TimeoutException: return None # because there were no Resources captured for the current web page - def mark(self, name) -> str: - js = 'return window.performance.mark("{}")[0];'.format(name) - start_mark = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMark not generated yet") - print(start_mark) - return PerformanceMark(**start_mark).name - - def measure(self, start_name) -> float: - end_name = self.mark("end") - js = 'return window.performance.measure("{}", "{}", "{}")[0];'.format("measure", start_name, end_name) - measures = self._wait().until(lambda driver: driver.execute_script(js),"PerformanceMeasure not generated yet") - print(measures) + def mark(self, mark): + js = 'return performance.mark("{}");'.format(mark) + self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMark not generated yet") + + def measure(self, start) -> float: + + js = 'return performance.measure("Measure", "{}");'.format(start) + measured = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMeasure not generated yet") + return PerformanceMeasure(**measured).duration class PerformanceMeasure(BaseModel): - """The PerformanceNavigationTiming Representation. + """The PerformanceMeasure Representation. Metrics regarding the browser's document navigation events @@ -131,7 +129,7 @@ class PerformanceMeasure(BaseModel): https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMeasure """ - detail: str = Field(alias="detail") + detail: None = Field(alias="detail") name: str = Field(alias="name") entry_type: str = Field(alias="entryType") start_time: float = Field(alias="startTime") @@ -146,7 +144,7 @@ class PerformanceMark(BaseModel): https://developer.mozilla.org/en-US/docs/Web/API/PerformanceMark """ - detail: str = Field(alias="detail") + detail: None = Field(alias="detail") name: str = Field(alias="name") entry_type: str = Field(alias="entryType") start_time: float = Field(alias="startTime") diff --git a/tests/test_flows.py b/tests/test_flows.py index 9a7472f..58a7f03 100644 --- a/tests/test_flows.py +++ b/tests/test_flows.py @@ -27,12 +27,12 @@ def test_add_to_cart_xpath(self, sauce: Pylenium): sauce.getx("//a[@class='shopping_cart_link']").click() assert sauce.findx("//*[@class='cart_item']").should().have_length(6) - def test_add_to_cart_xpath(sauce: Pylenium): + def test_add_to_cart_xpath(self, sauce: Pylenium): """Add 6 different items to the cart. There should be 6 items in the cart.""" - start_name = sauce.performance.mark("before") + sauce.performance.mark("Adding item in cart") for button in sauce.findx("//*[contains(@id, 'add-to-cart')]"): button.click() sauce.getx("//a[@class='shopping_cart_link']").click() + time_in_ms = sauce.performance.measure("Adding item in cart") assert sauce.findx("//*[@class='cart_item']").should().have_length(6) - time = sauce.performance.measure("measure", start_name) - assert time < 5, "Took longer than 5 seconds to add item to cart using xpath" + assert time_in_ms < 2000, "should be less 2000ms" From 67e3cb24df3f13e8b0dda7ab482e9645674cef8f Mon Sep 17 00:00:00 2001 From: bashang Date: Wed, 10 Jan 2024 01:39:04 +0800 Subject: [PATCH 4/6] update param --- pylenium/performance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylenium/performance.py b/pylenium/performance.py index 820d242..25ab9ca 100644 --- a/pylenium/performance.py +++ b/pylenium/performance.py @@ -113,9 +113,9 @@ def mark(self, mark): js = 'return performance.mark("{}");'.format(mark) self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMark not generated yet") - def measure(self, start) -> float: + def measure(self, mark) -> float: - js = 'return performance.measure("Measure", "{}");'.format(start) + js = 'return performance.measure("Measure", "{}");'.format(mark) measured = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMeasure not generated yet") return PerformanceMeasure(**measured).duration From 8966b3d6b4c43a4b9c53db168c9631b6cdab0c21 Mon Sep 17 00:00:00 2001 From: bashang Date: Wed, 10 Jan 2024 01:46:42 +0800 Subject: [PATCH 5/6] fix linter --- pylenium/performance.py | 1 - tests/test_flows.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pylenium/performance.py b/pylenium/performance.py index 25ab9ca..1e21d77 100644 --- a/pylenium/performance.py +++ b/pylenium/performance.py @@ -118,7 +118,6 @@ def measure(self, mark) -> float: js = 'return performance.measure("Measure", "{}");'.format(mark) measured = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMeasure not generated yet") return PerformanceMeasure(**measured).duration - class PerformanceMeasure(BaseModel): """The PerformanceMeasure Representation. diff --git a/tests/test_flows.py b/tests/test_flows.py index 58a7f03..3d407f6 100644 --- a/tests/test_flows.py +++ b/tests/test_flows.py @@ -27,8 +27,8 @@ def test_add_to_cart_xpath(self, sauce: Pylenium): sauce.getx("//a[@class='shopping_cart_link']").click() assert sauce.findx("//*[@class='cart_item']").should().have_length(6) - def test_add_to_cart_xpath(self, sauce: Pylenium): - """Add 6 different items to the cart. There should be 6 items in the cart.""" + def test_add_to_cart_xpath_duration(self, sauce: Pylenium): + """Add 6 different items to the cart. There should be 6 items in the cart. Duration should be less than 2000ms""" sauce.performance.mark("Adding item in cart") for button in sauce.findx("//*[contains(@id, 'add-to-cart')]"): button.click() From 7e17b10395da4cde1c2cc3f6061c46f7b46eb600 Mon Sep 17 00:00:00 2001 From: bashang Date: Wed, 10 Jan 2024 01:52:42 +0800 Subject: [PATCH 6/6] fix linter and docstring --- pylenium/performance.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pylenium/performance.py b/pylenium/performance.py index 1e21d77..502ade3 100644 --- a/pylenium/performance.py +++ b/pylenium/performance.py @@ -110,15 +110,17 @@ def get_resources(self): return None # because there were no Resources captured for the current web page def mark(self, mark): + """Add a named mark) to the browser's performance timeline.""" js = 'return performance.mark("{}");'.format(mark) self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMark not generated yet") def measure(self, mark) -> float: - + """Return duration in miliseconds""" js = 'return performance.measure("Measure", "{}");'.format(mark) measured = self._wait().until(lambda driver: driver.execute_script(js), "PerformanceMeasure not generated yet") return PerformanceMeasure(**measured).duration + class PerformanceMeasure(BaseModel): """The PerformanceMeasure Representation. @@ -134,6 +136,7 @@ class PerformanceMeasure(BaseModel): start_time: float = Field(alias="startTime") duration: float = Field(alias="duration") + class PerformanceMark(BaseModel): """The PerformanceMark Representation. @@ -149,6 +152,7 @@ class PerformanceMark(BaseModel): start_time: float = Field(alias="startTime") duration: float = Field(alias="duration") + class NavigationTiming(BaseModel): """The PerformanceNavigationTiming Representation.