Promium 3.6.1__tar.gz → 3.6.2__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.
- {promium-3.6.1 → promium-3.6.2}/PKG-INFO +1 -1
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/PKG-INFO +1 -1
- {promium-3.6.1 → promium-3.6.2}/promium/assertions.py +14 -1
- {promium-3.6.1 → promium-3.6.2}/promium/base.py +1 -0
- {promium-3.6.1 → promium-3.6.2}/promium/browsers.py +3 -0
- {promium-3.6.1 → promium-3.6.2}/promium/common.py +8 -0
- {promium-3.6.1 → promium-3.6.2}/promium/device_config.py +2 -2
- {promium-3.6.1 → promium-3.6.2}/promium/elements/frame.py +2 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/input_field.py +5 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/link.py +1 -0
- {promium-3.6.1 → promium-3.6.2}/promium/waits.py +8 -0
- {promium-3.6.1 → promium-3.6.2}/setup.py +1 -1
- {promium-3.6.1 → promium-3.6.2}/LICENSE +0 -0
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/SOURCES.txt +0 -0
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/dependency_links.txt +0 -0
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/entry_points.txt +0 -0
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/requires.txt +0 -0
- {promium-3.6.1 → promium-3.6.2}/Promium.egg-info/top_level.txt +0 -0
- {promium-3.6.1 → promium-3.6.2}/README.rst +0 -0
- {promium-3.6.1 → promium-3.6.2}/doc/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/doc/conf.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/checkbox.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/drop_downs.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/multiselect_listbox.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/radio_button.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/textarea_field.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/elements/upload_button.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/exceptions.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/expected_conditions.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/helpers.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/logger.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/plugin.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/support/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/support/settings.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/promium/test_case.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/setup.cfg +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/config.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/conftest.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/pages/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/pages/catalog_404_page.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/pages/catalog_gallery_page.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/__init__.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_base.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_chrome.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_edge.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_firefox.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_ie.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/settings/test_opera.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_catalog_404.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_catalog_gallery.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_enviroment.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_requests.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_soft_asserts.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/test_waits.py +0 -0
- {promium-3.6.1 → promium-3.6.2}/tests/urls.py +0 -0
|
@@ -303,6 +303,10 @@ class BaseSoftAssertion(object):
|
|
|
303
303
|
)
|
|
304
304
|
|
|
305
305
|
def soft_assert_dicts_with_ignore_types(self, current, expected, msg=''):
|
|
306
|
+
"""
|
|
307
|
+
Comparison of two dicts with ignoring type of values
|
|
308
|
+
If the dict key was lost, print it in missing list.
|
|
309
|
+
"""
|
|
306
310
|
expected_dict = _check_namedtuple(expected)
|
|
307
311
|
current_dict = _check_namedtuple(current)
|
|
308
312
|
errors = ''
|
|
@@ -331,7 +335,7 @@ class BaseSoftAssertion(object):
|
|
|
331
335
|
):
|
|
332
336
|
"""
|
|
333
337
|
Comparison by type, if the types do not match - compares in a string
|
|
334
|
-
If the dict key was lost, print
|
|
338
|
+
If the dict key was lost, print it in missing list.
|
|
335
339
|
"""
|
|
336
340
|
def _equal(
|
|
337
341
|
field_name: str,
|
|
@@ -405,26 +409,31 @@ class WebDriverSoftAssertion(BaseSoftAssertion):
|
|
|
405
409
|
)
|
|
406
410
|
|
|
407
411
|
def soft_assert_page_title(self, expected_title, msg=None):
|
|
412
|
+
"""Page title is equals to expected_title"""
|
|
408
413
|
default_msg = 'Wrong page title.'
|
|
409
414
|
error = f"{self.base_msg(default_msg=default_msg, extend_msg=msg)}"
|
|
410
415
|
self.soft_assert_equals(self.driver.title, expected_title, error)
|
|
411
416
|
|
|
412
417
|
def soft_assert_current_url(self, expected_url, msg=None):
|
|
418
|
+
"""Current url is equals to expected_title"""
|
|
413
419
|
default_msg = 'Wrong current url.'
|
|
414
420
|
error = f"{self.base_msg(default_msg=default_msg, extend_msg=msg)}"
|
|
415
421
|
self.soft_assert_equals(self.url, expected_url, error)
|
|
416
422
|
|
|
417
423
|
def soft_assert_current_url_contains(self, url_mask, msg=None):
|
|
424
|
+
"""Current url contains ulr mask"""
|
|
418
425
|
default_msg = f"URL {str(self.url)} doesn't contains {str(url_mask)}."
|
|
419
426
|
error = f"{self.base_msg(default_msg=default_msg, extend_msg=msg)}"
|
|
420
427
|
self.soft_assert_in(url_mask, self.url, error)
|
|
421
428
|
|
|
422
429
|
def soft_assert_current_url_not_contains(self, url_mask, msg=None):
|
|
430
|
+
"""Current url does not contain ulr mask"""
|
|
423
431
|
default_msg = f"URL {str(self.url)} contains {str(url_mask)}."
|
|
424
432
|
error = f"{self.base_msg(default_msg=default_msg, extend_msg=msg)}"
|
|
425
433
|
self.soft_assert_not_in(url_mask, self.url, error)
|
|
426
434
|
|
|
427
435
|
def soft_assert_element_is_present(self, element, msg=None):
|
|
436
|
+
"""Element is present"""
|
|
428
437
|
default_msg = (
|
|
429
438
|
f"Element {element.by}={element.locator} is not present "
|
|
430
439
|
f"on page at current time."
|
|
@@ -433,6 +442,7 @@ class WebDriverSoftAssertion(BaseSoftAssertion):
|
|
|
433
442
|
self.soft_assert_true(element.is_present(), error, with_screen=True)
|
|
434
443
|
|
|
435
444
|
def soft_assert_element_is_not_present(self, element, msg=None):
|
|
445
|
+
"""Element is not present"""
|
|
436
446
|
default_msg = (
|
|
437
447
|
f"Element {element.by}={element.locator} is found on page."
|
|
438
448
|
)
|
|
@@ -440,6 +450,7 @@ class WebDriverSoftAssertion(BaseSoftAssertion):
|
|
|
440
450
|
self.soft_assert_false(element.is_present(), error, with_screen=True)
|
|
441
451
|
|
|
442
452
|
def soft_assert_element_is_displayed(self, element, msg=None):
|
|
453
|
+
"""Element is displayed to user"""
|
|
443
454
|
default_msg = (
|
|
444
455
|
f"Element {element.by}={element.locator} is "
|
|
445
456
|
f"not visible to a user."
|
|
@@ -448,6 +459,7 @@ class WebDriverSoftAssertion(BaseSoftAssertion):
|
|
|
448
459
|
self.soft_assert_true(element.is_displayed(), error, with_screen=True)
|
|
449
460
|
|
|
450
461
|
def soft_assert_element_is_not_displayed(self, element, msg=None):
|
|
462
|
+
"""Element is not displayed to user"""
|
|
451
463
|
default_msg = (
|
|
452
464
|
f"Element {element.by}={element.locator} is visible to a user."
|
|
453
465
|
)
|
|
@@ -494,6 +506,7 @@ class WebDriverSoftAssertion(BaseSoftAssertion):
|
|
|
494
506
|
self.assertion_errors.append(error)
|
|
495
507
|
|
|
496
508
|
def soft_assert_image_status_code(self, image, status_code=200, msg=None):
|
|
509
|
+
"""Compare image url status code with expected status code"""
|
|
497
510
|
if not image.get_attribute('src'):
|
|
498
511
|
return self.assertion_errors.append(
|
|
499
512
|
'Image does not have attribute "src"'
|
|
@@ -150,6 +150,7 @@ class Page(object):
|
|
|
150
150
|
wait_for_page_loaded(self.driver)
|
|
151
151
|
|
|
152
152
|
def wait_for_source_changed(self, action_func, *args, **kwargs):
|
|
153
|
+
"""Waiting for status code of current page be changed"""
|
|
153
154
|
source = self.driver.page_source
|
|
154
155
|
action_func(*args, **kwargs)
|
|
155
156
|
wait_until(
|
|
@@ -51,6 +51,9 @@ def get_chrome_opera_options(
|
|
|
51
51
|
"profile.block_third_party_cookies": True
|
|
52
52
|
}
|
|
53
53
|
options.add_experimental_option("prefs", prefs)
|
|
54
|
+
options.add_experimental_option("excludeSwitches", [
|
|
55
|
+
"enable-automation", # disable the automation bar
|
|
56
|
+
])
|
|
54
57
|
# fix use window.onbeforeunload
|
|
55
58
|
options.enable_bidi = True
|
|
56
59
|
options.unhandled_prompt_behavior = 'ignore'
|
|
@@ -50,6 +50,7 @@ def scroll_to_bottom(driver):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def scroll_to_top(driver):
|
|
53
|
+
"""Scrolls to the top of the page"""
|
|
53
54
|
enable_jquery(driver)
|
|
54
55
|
driver.execute_script(
|
|
55
56
|
"""jQuery('html, body').animate({scrollTop: 0 }, 'slow', null);"""
|
|
@@ -58,6 +59,7 @@ def scroll_to_top(driver):
|
|
|
58
59
|
|
|
59
60
|
|
|
60
61
|
def scroll_to_bottom_in_block(driver, element_class):
|
|
62
|
+
"""Scrolls to the bottom of the current block"""
|
|
61
63
|
enable_jquery(driver)
|
|
62
64
|
script = """
|
|
63
65
|
var elem = '.'.concat(arguments[0]);
|
|
@@ -91,6 +93,10 @@ def scroll_to_element(driver, element, base_element=None):
|
|
|
91
93
|
|
|
92
94
|
|
|
93
95
|
def scroll_with_offset(driver, element, with_offset=0):
|
|
96
|
+
"""
|
|
97
|
+
Adjusting the final scroll position by adding or subtracting a
|
|
98
|
+
specified number of pixels
|
|
99
|
+
"""
|
|
94
100
|
enable_jquery(driver)
|
|
95
101
|
script = """
|
|
96
102
|
var elem = arguments[0];
|
|
@@ -235,11 +241,13 @@ def set_local_storage(driver, key, value):
|
|
|
235
241
|
|
|
236
242
|
|
|
237
243
|
def delete_cookie_item(driver, name):
|
|
244
|
+
"""Deleting cookie on current page"""
|
|
238
245
|
driver.delete_cookie(name)
|
|
239
246
|
driver.refresh()
|
|
240
247
|
|
|
241
248
|
|
|
242
249
|
def delete_element_from_dom(driver, element):
|
|
250
|
+
"""Removes a specific DOM element from the webpage"""
|
|
243
251
|
enable_jquery(driver)
|
|
244
252
|
driver.execute_script(f"""
|
|
245
253
|
var element = document.querySelector("{element}");
|
|
@@ -5,7 +5,7 @@ from typing import NamedTuple
|
|
|
5
5
|
DEFAULT_USER_AGENT_ANDROID = (
|
|
6
6
|
"Mozilla/5.0 (Linux; Android 14; SM-G960U) "
|
|
7
7
|
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
8
|
-
"Chrome/
|
|
8
|
+
"Chrome/131.0.0.0 Mobile Safari/537.36"
|
|
9
9
|
)
|
|
10
10
|
DEFAULT_USER_AGENT_IOS = (
|
|
11
11
|
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) "
|
|
@@ -15,7 +15,7 @@ DEFAULT_USER_AGENT_IOS = (
|
|
|
15
15
|
DEFAULT_USER_AGENT_HUAWEI = (
|
|
16
16
|
"Mozilla/5.0 (Linux; Android 11; HUAWEI Mate 40 Pro Build/HUAWEIMate40Pro; "
|
|
17
17
|
"xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
18
|
-
"Chrome/
|
|
18
|
+
"Chrome/131.0.0.0 Mobile Safari/537.36"
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
@@ -5,7 +5,9 @@ from promium.base import Element
|
|
|
5
5
|
class Frame(Element):
|
|
6
6
|
|
|
7
7
|
def switch_to_frame(self):
|
|
8
|
+
"""Switch the focus from the main page content to the specific iframe"""
|
|
8
9
|
self.driver.switch_to.frame(self.lookup())
|
|
9
10
|
|
|
10
11
|
def exit_from_frame(self):
|
|
12
|
+
"""Switch the focus from the specific iframe to the main page content"""
|
|
11
13
|
self.driver.switch_to.window(self.driver.current_window_handle)
|
|
@@ -36,10 +36,14 @@ class InputField(Element):
|
|
|
36
36
|
return self.lookup().send_keys(*value)
|
|
37
37
|
|
|
38
38
|
def _clear_field_with_keyboard(self):
|
|
39
|
+
"""Clear the field using keyboard keys"""
|
|
39
40
|
self.send_keys(f'{Keys.CONTROL}a')
|
|
40
41
|
self.send_keys(Keys.BACKSPACE)
|
|
41
42
|
|
|
42
43
|
def clear_and_fill(self, text):
|
|
44
|
+
"""
|
|
45
|
+
Clear the field using keyboard keys and fill it with the given text
|
|
46
|
+
"""
|
|
43
47
|
expected_text = str(text).lower()
|
|
44
48
|
self._clear_field_with_keyboard()
|
|
45
49
|
self.send_keys(text)
|
|
@@ -51,6 +55,7 @@ class InputField(Element):
|
|
|
51
55
|
)
|
|
52
56
|
|
|
53
57
|
def fill_field(self, text):
|
|
58
|
+
"""Clear element value if exists and fills it with the given text"""
|
|
54
59
|
expected_text = str(text).lower()
|
|
55
60
|
if self.value:
|
|
56
61
|
self.clear()
|
|
@@ -169,6 +169,7 @@ def wait_document_status(driver, seconds=NORMAL_LOAD_TIME):
|
|
|
169
169
|
|
|
170
170
|
|
|
171
171
|
def wait_websocket_connection_open(driver, seconds=NORMAL_LOAD_TIME):
|
|
172
|
+
"""Waiting for websocket connection to be opened"""
|
|
172
173
|
wait = WebDriverWait(driver, timeout=seconds)
|
|
173
174
|
try:
|
|
174
175
|
wait.until(
|
|
@@ -182,6 +183,7 @@ def wait_websocket_connection_open(driver, seconds=NORMAL_LOAD_TIME):
|
|
|
182
183
|
|
|
183
184
|
|
|
184
185
|
def wait_jquery_status(driver, seconds=NORMAL_LOAD_TIME):
|
|
186
|
+
"""Wait for jquery will pass to active status"""
|
|
185
187
|
wait = WebDriverWait(driver, timeout=seconds)
|
|
186
188
|
try:
|
|
187
189
|
wait.until(
|
|
@@ -220,6 +222,7 @@ def wait_for_alert(driver, seconds=NORMAL_LOAD_TIME):
|
|
|
220
222
|
|
|
221
223
|
|
|
222
224
|
def wait_for_alert_is_displayed(driver, seconds=NORMAL_LOAD_TIME):
|
|
225
|
+
"""Wait for alert to be displayed"""
|
|
223
226
|
try:
|
|
224
227
|
wait_for_alert(driver, seconds=seconds)
|
|
225
228
|
except TimeoutException:
|
|
@@ -246,6 +249,7 @@ def wait_for_status_code(url, status_code=200, tries=10, allow_redirects=True):
|
|
|
246
249
|
|
|
247
250
|
|
|
248
251
|
def wait_until_new_window_is_opened(driver, original_window, window_num=0):
|
|
252
|
+
"""Wait until new window is opened in session"""
|
|
249
253
|
wait_until(
|
|
250
254
|
driver,
|
|
251
255
|
lambda x: len(driver.window_handles) >= 2,
|
|
@@ -257,6 +261,7 @@ def wait_until_new_window_is_opened(driver, original_window, window_num=0):
|
|
|
257
261
|
|
|
258
262
|
|
|
259
263
|
def wait_part_appear_in_class(driver, obj, part_class, msg=None):
|
|
264
|
+
"""Wait some text in html class of the object"""
|
|
260
265
|
if not msg:
|
|
261
266
|
msg = f'"{part_class}" not present in attribute *class*.'
|
|
262
267
|
wait_until(
|
|
@@ -268,6 +273,7 @@ def wait_part_appear_in_class(driver, obj, part_class, msg=None):
|
|
|
268
273
|
|
|
269
274
|
|
|
270
275
|
def wait_part_disappear_in_class(driver, obj, part_class, msg=None):
|
|
276
|
+
"""Wait some text not in html class of the object"""
|
|
271
277
|
if not msg:
|
|
272
278
|
msg = f'"{part_class}" not present in attribute *class*.'
|
|
273
279
|
wait_until(
|
|
@@ -279,12 +285,14 @@ def wait_part_disappear_in_class(driver, obj, part_class, msg=None):
|
|
|
279
285
|
|
|
280
286
|
|
|
281
287
|
def wait_url_contains(driver, text, msg=None, timeout=5):
|
|
288
|
+
"""Wait some text is present in current url"""
|
|
282
289
|
if not msg:
|
|
283
290
|
msg = f'"{text}" not present in current url {driver.current_url}.'
|
|
284
291
|
wait_until(driver, EC.url_contains(text), seconds=timeout, msg=msg)
|
|
285
292
|
|
|
286
293
|
|
|
287
294
|
def wait_url_not_contains(driver, text, msg=None, timeout=5):
|
|
295
|
+
"""Wait some text is not present in current url"""
|
|
288
296
|
if not msg:
|
|
289
297
|
msg = f'"{text}" not disappear in url.'
|
|
290
298
|
wait_until_not(driver, EC.url_contains(text), seconds=timeout, msg=msg)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|