pomcorn 0.9.3__tar.gz → 0.10.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pomcorn might be problematic. Click here for more details.

@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pomcorn
3
- Version: 0.9.3
3
+ Version: 0.10.1
4
4
  Summary: Base implementation of Page Object Model
5
- Home-page: https://pypi.org/project/pomcorn/
6
5
  License: MIT
6
+ License-File: LICENSE
7
7
  Keywords: python,selenium,webdriver,autotests,page object model,page object pattern,page object,pom,parsing,browser
8
8
  Author: Saritasa
9
9
  Author-email: pypi@saritasa.com
@@ -18,9 +18,12 @@ Classifier: Operating System :: OS Independent
18
18
  Classifier: Programming Language :: Python :: 3
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
21
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
24
  Requires-Dist: selenium (>=4.12)
23
25
  Project-URL: Documentation, http://pomcorn.rtfd.io/
26
+ Project-URL: Homepage, https://pypi.org/project/pomcorn/
24
27
  Project-URL: Repository, https://github.com/saritasa-nest/pomcorn/
25
28
  Description-Content-Type: text/markdown
26
29
 
@@ -62,7 +62,7 @@ class Component(Generic[TPage], WebView):
62
62
  super().__init__(
63
63
  page.webdriver,
64
64
  app_root=page.app_root,
65
- wait_timeout=page.wait_timeout,
65
+ wait_timeout=page.wait._timeout,
66
66
  )
67
67
  self.page = page
68
68
  self.base_locator = base_locator or self.base_locator
@@ -174,13 +174,25 @@ class Component(Generic[TPage], WebView):
174
174
  return locator
175
175
  return self.base_locator // relative_locator
176
176
 
177
- def wait_until_visible(self, **kwargs):
178
- """Wait until component becomes visible."""
179
- self.body.wait_until_visible()
177
+ def wait_until_visible(self, timeout: float | None = None, **kwargs):
178
+ """Wait until component becomes visible.
180
179
 
181
- def wait_until_invisible(self, **kwargs):
182
- """Wait until component becomes invisible."""
183
- self.body.wait_until_invisible()
180
+ By default, method waits for `self.wait._timeout` seconds.
181
+ If you need to change timeout, you can specify it in `timeout`
182
+ argument.
183
+
184
+ """
185
+ self.body.wait_until_visible(timeout)
186
+
187
+ def wait_until_invisible(self, timeout: float | None = None, **kwargs):
188
+ """Wait until component becomes invisible.
189
+
190
+ By default, method waits for `self.wait._timeout` seconds.
191
+ If you need to change timeout, you can specify it in `timeout`
192
+ argument.
193
+
194
+ """
195
+ self.body.wait_until_invisible(timeout)
184
196
 
185
197
 
186
198
  # Here type ignore added because we can't specify TPage as generic for
@@ -349,12 +361,11 @@ class ListComponent(Generic[ListItemType, TPage], Component[TPage]):
349
361
 
350
362
  return False
351
363
 
352
- def get_item_by_text(self, text: str) -> ListItemType:
364
+ def get_item_by_text(self, text: str, exact: bool = False) -> ListItemType:
353
365
  """Get list item by text."""
354
- locator = self.base_item_locator.extend_query(
355
- extra_query=(
356
- f"[contains(., {self.base_item_locator._escape_quotes(text)})]"
357
- ),
366
+ locator = self.base_item_locator.contains(
367
+ text=text,
368
+ exact=exact,
358
369
  )
359
370
  return self._item_class(page=self.page, base_locator=locator)
360
371
 
@@ -33,58 +33,101 @@ class PomcornElement(Generic[locators.TLocator]):
33
33
  self.web_view = web_view
34
34
  self.locator = locator
35
35
 
36
- def wait_until_visible(self):
36
+ def wait_until_visible(self, timeout: float | None = None):
37
37
  """Wait until element becomes visible.
38
38
 
39
+ By default, method waits for `self.web_view.wait_timeout` seconds.
40
+ If you need to change timeout, you can specify it in `timeout`
41
+ argument.
42
+
39
43
  Raises:
40
- TimeoutException: If after `self.wait_timeout` seconds the wait
41
- has not ended.
44
+ TimeoutException: If after `self.web_view.wait_timeout` seconds
45
+ the wait has not ended.
42
46
 
43
47
  """
44
- self.web_view.wait_until_locator_visible(locator=self.locator)
48
+ self.web_view.wait_until_locator_visible(
49
+ locator=self.locator,
50
+ timeout=timeout,
51
+ )
45
52
 
46
- def wait_until_invisible(self):
53
+ def wait_until_invisible(
54
+ self,
55
+ timeout: float | None = None,
56
+ ):
47
57
  """Wait until element becomes invisible.
48
58
 
59
+ By default, method waits for `self.web_view.wait_timeout` seconds.
60
+ If you need to change timeout, you can specify it in `timeout`
61
+ argument.
62
+
49
63
  Raises:
50
- TimeoutException: If after `self.wait_timeout` seconds the wait
51
- has not ended.
64
+ TimeoutException: If after `self.web_view.wait_timeout` seconds
65
+ the wait has not ended.
52
66
 
53
67
  """
54
- self.web_view.wait_until_locator_invisible(locator=self.locator)
68
+ self.web_view.wait_until_locator_invisible(
69
+ locator=self.locator,
70
+ timeout=timeout,
71
+ )
55
72
 
56
- def wait_until_clickable(self):
73
+ def wait_until_clickable(
74
+ self,
75
+ timeout: float | None = None,
76
+ ):
57
77
  """Wait until element becomes clickable.
58
78
 
79
+ By default, method waits for `self.web_view.wait_timeout` seconds.
80
+ If you need to change timeout, you can specify it in `timeout`
81
+ argument.
82
+
59
83
  Raises:
60
- TimeoutException: If after `self.wait_timeout` seconds the wait
61
- has not ended.
84
+ TimeoutException: If after `self.web_view.wait_timeout` seconds
85
+ the wait has not ended.
62
86
 
63
87
  """
64
- self.web_view.wait_until_clickable(locator=self.locator)
88
+ self.web_view.wait_until_clickable(
89
+ locator=self.locator,
90
+ timeout=timeout,
91
+ )
65
92
 
66
- def wait_until_text_is_in_element(self, text: str):
93
+ def wait_until_text_is_in_element(
94
+ self,
95
+ text: str,
96
+ timeout: float | None = None,
97
+ ):
67
98
  """Wait until text is present in element.
68
99
 
100
+ By default, method waits for `self.web_view.wait_timeout` seconds.
101
+ If you need to change timeout, you can specify it in `timeout`
102
+ argument.
103
+
69
104
  Raises:
70
- TimeoutException: If after `self.wait_timeout` seconds the wait
71
- has not ended.
105
+ TimeoutException: If after `self.web_view.wait_timeout` seconds
106
+ the wait has not ended.
72
107
 
73
108
  """
74
109
  self.web_view.wait_until_text_is_in_element(
75
110
  text=text,
76
111
  locator=self.locator,
112
+ timeout=timeout,
77
113
  )
78
114
 
79
- def wait_until_not_exists_in_dom(self):
115
+ def wait_until_not_exists_in_dom(self, timeout: float | None = None):
80
116
  """Wait until element ceases to exist in DOM.
81
117
 
118
+ By default, method waits for `self.web_view.wait_timeout` seconds.
119
+ If you need to change timeout, you can specify it in `timeout`
120
+ argument.
121
+
82
122
  Raises:
83
- TimeoutException: If after `self.wait_timeout` seconds the wait
84
- has not ended.
123
+ TimeoutException: If after `self.web_view.wait_timeout` seconds
124
+ the wait has not ended.
85
125
 
86
126
  """
87
- self.web_view.wait_until_not_exists_in_dom(self.locator)
127
+ self.web_view.wait_until_not_exists_in_dom(
128
+ element=self.locator,
129
+ timeout=timeout,
130
+ )
88
131
 
89
132
  def get_element(self, only_visible: bool = True) -> WebElement:
90
133
  """Get selenium instance(WebElement) of element.
@@ -122,13 +122,14 @@ class Page(WebView):
122
122
  self.webdriver.refresh()
123
123
  self.wait_until_loaded()
124
124
 
125
- def wait_until_loaded(self) -> None:
125
+ def wait_until_loaded(self, timeout: float | None = None) -> None:
126
126
  """Wait until page is loaded."""
127
- self.wait.until(
127
+ wait = self.get_wait(timeout)
128
+ wait.until(
128
129
  method=lambda _: self.check_page_is_loaded(),
129
130
  message=(
130
131
  f"Page `{self.__class__}` didn't loaded in "
131
- f"{self.wait_timeout} seconds! Didn't wait for `True` from "
132
+ f"{wait._timeout} seconds! Didn't wait for `True` from "
132
133
  "`check_page_is_loaded` method."
133
134
  ),
134
135
  )
@@ -20,7 +20,7 @@ class WebView:
20
20
  webdriver: WebDriver,
21
21
  *,
22
22
  app_root: str,
23
- wait_timeout: int,
23
+ wait_timeout: float,
24
24
  poll_frequency: float = 0,
25
25
  ):
26
26
  """Initialize webview.
@@ -37,11 +37,8 @@ class WebView:
37
37
  self.webdriver = webdriver
38
38
  self.app_root = app_root
39
39
  self.wait_timeout = wait_timeout
40
- self.wait = WebDriverWait(
41
- driver=webdriver,
42
- timeout=wait_timeout,
43
- poll_frequency=poll_frequency,
44
- )
40
+ self.poll_frequency = poll_frequency
41
+ self.wait = self.get_wait(self.wait_timeout)
45
42
 
46
43
  def init_element(
47
44
  self,
@@ -125,6 +122,24 @@ class WebView:
125
122
  )
126
123
  return result
127
124
 
125
+ def get_wait(
126
+ self,
127
+ timeout: float | None = None,
128
+ ) -> WebDriverWait[WebDriver]:
129
+ """Get `WebDriverWait` instance.
130
+
131
+ If no arguments are provided, returns the default wait instance.
132
+
133
+ """
134
+ if not timeout:
135
+ return self.wait
136
+
137
+ return WebDriverWait(
138
+ driver=self.webdriver,
139
+ timeout=timeout,
140
+ poll_frequency=self.poll_frequency,
141
+ )
142
+
128
143
  @property
129
144
  def current_url(self) -> str:
130
145
  """Return the current webdriver URL."""
@@ -168,116 +183,162 @@ class WebView:
168
183
  self.wait_until_locator_visible(locator=locator)
169
184
  return self.webdriver.find_elements(*locator)
170
185
 
171
- def wait_until_url_contains(self, url: str):
186
+ def wait_until_url_contains(
187
+ self,
188
+ url: str,
189
+ timeout: float | None = None,
190
+ ) -> None:
172
191
  """Wait until browser's url contains input url.
173
192
 
193
+ By default, method waits for `self.wait_timeout` seconds.
194
+ If you need to change timeout, you can specify it in `timeout`
195
+ argument.
196
+
174
197
  Raises:
175
- TimeoutException: If after `self.wait_timeout` seconds the wait
198
+ TimeoutException: If after `self.wait._timeout` seconds the wait
176
199
  has not ended.
177
200
 
178
201
  """
179
- self.wait.until(
202
+ wait = self.get_wait(timeout)
203
+ wait.until(
180
204
  method=expected_conditions.url_contains(url),
181
205
  message=(
182
- f"Url doesn't contain `{url}` in {self.wait_timeout} seconds! "
183
- f"The current URL is `{self.current_url}`."
206
+ f"Url doesn't contain `{url}` in {wait._timeout} "
207
+ f"seconds! The current URL is `{self.current_url}`."
184
208
  ),
185
209
  )
186
210
 
187
- def wait_until_url_not_contains(self, url: str):
211
+ def wait_until_url_not_contains(
212
+ self,
213
+ url: str,
214
+ timeout: float | None = None,
215
+ ) -> None:
188
216
  """Wait until browser's url doesn't not contains input url.
189
217
 
218
+ By default, method waits for `self.wait_timeout` seconds.
219
+ If you need to change timeout, you can specify it in `timeout`
220
+ argument.
221
+
190
222
  Raises:
191
- TimeoutException: If after `self.wait_timeout` seconds the wait
223
+ TimeoutException: If after `self.wait._timeout` seconds the wait
192
224
  has not ended.
193
225
 
194
226
  """
195
- self.wait.until(
227
+ wait = self.get_wait(timeout)
228
+ wait.until(
196
229
  method=waits_conditions.url_not_matches(url),
197
230
  message=(
198
- f"Url does contain `{url}` in {self.wait_timeout} seconds! "
231
+ f"Url does contain `{url}` in {wait._timeout} seconds! "
199
232
  f"The current URL is `{self.current_url}`."
200
233
  ),
201
234
  )
202
235
 
203
- def wait_until_url_changes(self, url: str | None = None):
236
+ def wait_until_url_changes(
237
+ self,
238
+ url: str | None = None,
239
+ timeout: float | None = None,
240
+ ) -> None:
204
241
  """Wait until url changes.
205
242
 
206
243
  Args:
207
244
  url: Browser URL which should be changed. If the argument is not
208
245
  input, will be used `self.current_url`.
246
+ timeout: Number of seconds to wait until timing out. By default,
247
+ method waits for `self.wait_timeout` seconds.
209
248
 
210
249
  Raises:
211
- TimeoutException: If after `self.wait_timeout` seconds the wait
250
+ TimeoutException: If after `self.wait._timeout` seconds the wait
212
251
  has not ended.
213
252
 
214
253
  """
215
254
  url = url or self.current_url
216
- self.wait.until(
255
+ wait = self.get_wait(timeout)
256
+ wait.until(
217
257
  method=expected_conditions.url_changes(url),
218
258
  message=(
219
- f"Url didn't changed from {url} in {self.wait_timeout} "
259
+ f"Url didn't changed from {url} in {wait._timeout} "
220
260
  f"seconds! The current URL is `{self.current_url}`."
221
261
  ),
222
262
  )
223
263
 
224
- def wait_until_locator_visible(self, locator: locators.Locator):
264
+ def wait_until_locator_visible(
265
+ self,
266
+ locator: locators.Locator,
267
+ timeout: float | None = None,
268
+ ) -> None:
225
269
  """Wait until element matching locator becomes visible.
226
270
 
227
271
  Args:
228
272
  locator: Instance of a class to locate the element in the browser.
273
+ timeout: Number of seconds to wait until timing out. By default,
274
+ method waits for `self.wait_timeout` seconds.
229
275
 
230
276
  Raises:
231
- TimeoutException: If after `self.wait_timeout` seconds the wait
277
+ TimeoutException: If after `self.wait._timeout` seconds the wait
232
278
  has not ended.
233
279
 
234
280
  """
235
- self.wait.until(
281
+ wait = self.get_wait(timeout)
282
+ wait.until(
236
283
  method=expected_conditions.visibility_of_element_located(
237
284
  locator=(locator.by, locator.query),
238
285
  ),
239
286
  message=(
240
- f"Unable to locate {locator} in {self.wait_timeout} seconds!"
287
+ f"Unable to locate {locator} in {wait._timeout} seconds!"
241
288
  ),
242
289
  )
243
290
 
244
- def wait_until_locator_invisible(self, locator: locators.Locator):
291
+ def wait_until_locator_invisible(
292
+ self,
293
+ locator: locators.Locator,
294
+ timeout: float | None = None,
295
+ ) -> None:
245
296
  """Wait until element matching locator becomes invisible.
246
297
 
247
298
  Args:
248
299
  locator: Instance of a class to locate the element in the browser.
300
+ timeout: Number of seconds to wait until timing out. By default,
301
+ method waits for `self.wait_timeout` seconds.
249
302
 
250
303
  Raises:
251
- TimeoutException: If after `self.wait_timeout` seconds the wait
304
+ TimeoutException: If after `self.wait._timeout` seconds the wait
252
305
  has not ended.
253
306
 
254
307
  """
255
- self.wait.until(
308
+ wait = self.get_wait(timeout)
309
+ wait.until(
256
310
  method=expected_conditions.invisibility_of_element_located(
257
311
  locator=(locator.by, locator.query),
258
312
  ),
259
313
  message=(
260
- f"{locator} is still visible in {self.wait_timeout} seconds!"
314
+ f"{locator} is still visible in {wait._timeout} seconds!"
261
315
  ),
262
316
  )
263
317
 
264
- def wait_until_clickable(self, locator: locators.Locator):
318
+ def wait_until_clickable(
319
+ self,
320
+ locator: locators.Locator,
321
+ timeout: float | None = None,
322
+ ) -> None:
265
323
  """Wait until element matching locator becomes clickable.
266
324
 
267
325
  Args:
268
326
  locator: Instance of a class to locate the element in the browser.
327
+ timeout: Number of seconds to wait until timing out. By default,
328
+ method waits for `self.wait_timeout` seconds.
269
329
 
270
330
  Raises:
271
- TimeoutException: If after `self.wait_timeout` seconds the wait
331
+ TimeoutException: If after `self.wait._timeout` seconds the wait
272
332
  has not ended.
273
333
 
274
334
  """
275
- self.wait.until(
335
+ wait = self.get_wait(timeout)
336
+ wait.until(
276
337
  method=expected_conditions.element_to_be_clickable(
277
338
  mark=(locator.by, locator.query),
278
339
  ),
279
340
  message=(
280
- f"{locator} isn't clickable after {self.wait_timeout} seconds!"
341
+ f"{locator} isn't clickable after {wait._timeout} seconds!"
281
342
  ),
282
343
  )
283
344
 
@@ -285,25 +346,29 @@ class WebView:
285
346
  self,
286
347
  text: str,
287
348
  locator: locators.Locator,
288
- ):
349
+ timeout: float | None = None,
350
+ ) -> None:
289
351
  """Wait until text is present in the specified element by locator.
290
352
 
291
353
  Args:
292
354
  locator: Instance of a class to locate the element in the browser.
293
355
  text: Text that should be presented in element.
356
+ timeout: Number of seconds to wait until timing out. By default,
357
+ method waits for `self.wait_timeout` seconds.
294
358
 
295
359
  Raises:
296
- TimeoutException: If after `self.wait_timeout` seconds the wait
360
+ TimeoutException: If after `self.wait._timeout` seconds the wait
297
361
  has not ended.
298
362
 
299
363
  """
300
- self.wait.until(
364
+ wait = self.get_wait(timeout)
365
+ wait.until(
301
366
  method=expected_conditions.text_to_be_present_in_element(
302
367
  locator=(locator.by, locator.query),
303
368
  text_=text,
304
369
  ),
305
370
  message=(
306
- f"{locator} doesn't have `{text}` after {self.wait_timeout} "
371
+ f"{locator} doesn't have `{text}` after {wait._timeout} "
307
372
  "seconds!"
308
373
  ),
309
374
  )
@@ -311,22 +376,26 @@ class WebView:
311
376
  def wait_until_not_exists_in_dom(
312
377
  self,
313
378
  element: PomcornElement[locators.TLocator] | locators.TLocator,
379
+ timeout: float | None = None,
314
380
  ):
315
381
  """Wait until element ceases to exist in DOM.
316
382
 
317
383
  Args:
318
384
  element: Instance of a class to locate the element in the browser
319
385
  or instance of element.
386
+ timeout: Number of seconds to wait until timing out. By default,
387
+ method waits for `self.wait_timeout` seconds.
320
388
 
321
389
  Raises:
322
- TimeoutException: If after `self.wait_timeout` seconds the wait
390
+ TimeoutException: If after `self.wait._timeout` seconds the wait
323
391
  has not ended.
324
392
 
325
393
  """
326
- self.wait.until(
394
+ wait = self.get_wait(timeout)
395
+ wait.until(
327
396
  method=waits_conditions.element_not_exists_in_dom(element),
328
397
  message=(
329
- f"{element} is still exists in DOM after {self.wait_timeout} "
398
+ f"{element} is still exists in DOM after {wait._timeout} "
330
399
  "seconds!"
331
400
  ),
332
401
  )
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pomcorn"
3
- version = "0.9.3"
3
+ version = "0.10.1"
4
4
  description = "Base implementation of Page Object Model"
5
5
  authors = [
6
6
  "Saritasa <pypi@saritasa.com>",
File without changes
File without changes
File without changes
File without changes