diff --git a/CHANGELOG.md b/CHANGELOG.md
index d129880d..59c2c8b2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -156,9 +156,7 @@ check vscode pylance, mypy, jetbrains qodana...
### TODO: consider regex support via .pattern prop (similar to .ignore_case) (#537)
-### TODO: decide on ... vs (...,) as one_or_more
-
-consider customizing them via config
+### TODO: customize ... vs (...,) as one_or_more, etc. – via config option
### Deprecated conditions
@@ -242,11 +240,11 @@ browser.all('li').should(have.texts_matching(
))
# that is also equivalent to:
browser.all('li').should(have._texts_like(
- r'\d\) One(.)\1\1', ..., ...
+ r'\d\) One(.)\1\1', {...}, {...}
).with_regex)
# or even:
browser.all('li').should(have._texts_like(
- r'\d\) One(.)\1\1', (...,) # = one or more
+ r'\d\) One(.)\1\1', ..., # = one or more
).with_regex)
# And with smart approach you can mix to achieve more with less:
browser.all('li')[:3].should(have.text_matching(
@@ -273,10 +271,10 @@ List of collection conditions added (still marked as experimental with `_` prefi
Where:
- default list glob placeholders are:
- - `[...]` matches **zero or one** item of any text in the list
- - `...` matches **exactly one** item of any text in the list
- - `(...,)` matches one **or more** items of any text in the list
- - `[(...,)]` matches **zero** or more items of any text in the list
+ - `[{...}]` matches **zero or one** item of any text in the list
+ - `{...}` matches **exactly one** item of any text in the list
+ - `...` matches one **or more** items of any text in the list
+ - `[...]` matches **zero** or more items of any text in the list
- all globbing placeholders can be mixed in the same list of expected items in any order
- regex patterns can't use `^` (start of text) and `$` (end of text)
because they are implicit, and if added explicitly will break the match
@@ -288,7 +286,7 @@ Where:
Warning:
-- Actual implementation does not compare each list item separately, it merges all expected items into one regex pattern and matches it with merged text of all visible elements collection texts, and so it may be tricky to analyze the error message in case of failure. To keep life simpler, try to reduce the usage of such conditions to the simplest cases, preferring wildcards to regex patterns, trying even to avoid wildcards if possible, in the perfect end, sticking just to `exact_texts_like` or `texts_like` conditions with only one explicitly (for readability) customized list glob, choosing `...` as the simplest glob placeholder, for example: `browser.all('li').should(have._exact_texts_like(1, 2, 'Three', ...).where(one_or_more=...))` to assert actual texts `
12Three45` in the list.
+- Actual implementation does not compare each list item separately, it merges all expected items into one regex pattern and matches it with merged text of all visible elements collection texts, and so it may be tricky to analyze the error message in case of failure. To keep life simpler, try to reduce the usage of such conditions to the simplest cases, preferring wildcards to regex patterns, trying even to avoid wildcards if possible, in the perfect end, sticking just to `exact_texts_like` or `texts_like` conditions with only one explicitly (for readability) customized list glob, choosing `...` as the simplest glob placeholder depending on context, for example, to assert actual texts `12Three45` in the list, if you want to match "one or more" – define `...` explicitely: `browser.all('li').should(have._exact_texts_like(1, 2, 'Three', ...).where(one_or_more=...))`, and if you want to match "exactly one" – again, use same `...` defined explicitly: `browser.all('li').should(have._exact_texts_like(1, ..., ..., 4, 5).where(exactly_one=...))`.
Examples of usage:
@@ -308,37 +306,37 @@ from selene import browser, have
# )
browser.all('li').should(have._exact_texts_like(
- '1) One!!!', '2) Two!!!', ..., ..., ... # = exactly one
+ '1) One!!!', '2) Two!!!', {...}, {...}, {...} # = exactly one
))
browser.all('li').should(have._texts_like(
- r'\d\) One!+', r'\d.*', ..., ..., ...
+ r'\d\) One!+', r'\d.*', {...}, {...}, {...}
).with_regex)
browser.all('li').should(have._texts_like(
- '?) One*', '?) Two*', ..., ..., ...
+ '?) One*', '?) Two*', {...}, {...}, {...}
).with_wildcards)
browser.all('li').should(have._texts_like(
- '_) One**', '_) Two*', ..., ..., ...
+ '_) One**', '_) Two*', {...}, {...}, {...}
).where_wildcards(zero_or_more='**', exactly_one='_'))
browser.all('li').should(have._texts_like(
- 'One', 'Two', ..., ..., ... # matches each text by contains
+ 'One', 'Two', {...}, {...}, {...} # matches each text by contains
)) # kind of "with implicit * wildcards" in the beginning and the end of each text
browser.all('li').should(have._texts_like(
- ..., ..., ..., 'Four', 'Five'
+ {...}, {...}, {...}, 'Four', 'Five'
))
browser.all('li').should(have._texts_like(
- 'One', ..., ..., 'Four', 'Five'
+ 'One', {...}, {...}, 'Four', 'Five'
))
browser.all('li').should(have._texts_like(
- 'One', 'Two', (..., ) # = one or more
+ 'One', 'Two', ... # = one or more
))
browser.all('li').should(have._texts_like(
- [(..., )], 'One', 'Two', [(..., )] # = ZERO or more ;)
+ [...], 'One', 'Two', [...] # = ZERO or more ;)
))
browser.all('li').should(have._texts_like(
- [...,], 'One', 'Two', 'Three', 'Four', [...] # = zero or ONE ;)
+ [{...}], 'One', 'Two', 'Three', 'Four', [{...}] # = zero or ONE ;)
))
# If you don't need so much "globs"...
@@ -346,12 +344,15 @@ browser.all('li').should(have._texts_like(
# to keep things simpler for easier support and more explicit for readability)
# – you can use the simplest glob item with explicitly customized meaning:
browser.all('li').should(have._exact_texts_like(
- 'One', 'Two', ... # = one OR MORE
-).where(one_or_more=...)) # – because the ... meaning was overridden
+ 'One', 'Two', ..., ..., ... # = exactly one
+).where(one_or_more=...)) # – because the ... meaning was overridden
+browser.all('li').should(have._exact_texts_like(
+ ..., 'One', 'Two', ... # = one OR MORE
+).where(zero_or_more=...)) # – because the ... meaning was overriden
# Same works for other conditions that end with `_like`
browser.all('li').should(have._exact_texts_like(
'1) One!!!', '2) Two!!!', ...
-).where(one_or_more=...))
+).where(zero_or_more=...))
```
### Text related now supports ignore_case (including regex conditions)
diff --git a/selene/core/match.py b/selene/core/match.py
index 1aa6a87a..51070de5 100644
--- a/selene/core/match.py
+++ b/selene/core/match.py
@@ -962,6 +962,13 @@ class _exact_texts_like(Condition[Collection]):
_MATCHING_EMPTY_STRING_MARKER = '‹EMTPY_STRING›'
_RENDERING_SEPARATOR = ', '
_RENDERING_TRANSLATIONS = (
+ ({...}, '{...}'),
+ ([{...}], '[{...}]'),
+ (..., '...'),
+ ([...], '[...])'),
+ )
+ # initially designed version
+ __X_RENDERING_TRANSLATIONS = (
(..., '...'),
([...], '[...]'),
((...,), '(...,)'),
@@ -982,15 +989,15 @@ class _exact_texts_like(Condition[Collection]):
zero_or_more=r'.*?',
)
- _DEFAULT_GLOBS: Tuple[Tuple[Any, str], ...] = (
+ # todo: initial default globs version
+ __X_DEFAULT_GLOBS: Tuple[Tuple[Any, str], ...] = (
(..., _PredefinedGlobPatterns['exactly_one']),
([...], _PredefinedGlobPatterns['zero_or_one']),
((...,), _PredefinedGlobPatterns['one_or_more']),
([(...,)], _PredefinedGlobPatterns['zero_or_more']),
)
- # TODO: consider this set of list globs as a default
- __X_DEFAULT_GLOBS: Tuple[Tuple[Any, str], ...] = (
+ _DEFAULT_GLOBS: Tuple[Tuple[Any, str], ...] = (
({...}, _PredefinedGlobPatterns['exactly_one']),
([{...}], _PredefinedGlobPatterns['zero_or_one']),
(..., _PredefinedGlobPatterns['one_or_more']),
diff --git a/tests/integration/condition__collection__have_exact_texts_like__with_ellipsis_globbing_test.py b/tests/integration/condition__collection__have_exact_texts_like__with_ellipsis_globbing_test.py
index 54f74272..feef6725 100644
--- a/tests/integration/condition__collection__have_exact_texts_like__with_ellipsis_globbing_test.py
+++ b/tests/integration/condition__collection__have_exact_texts_like__with_ellipsis_globbing_test.py
@@ -188,7 +188,7 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
'Zero',
1,
'Two',
- [(...,)], # means zero or MORE and so does match 2 texts
+ [...], # means zero or MORE and so does match 2 texts
"'Five'",
6,
7, # here list ends
@@ -197,10 +197,10 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- ...,
+ {...},
1,
'Two',
- [(...,)], # means zero or MORE and so does match 2 texts
+ [...], # means zero or MORE and so does match 2 texts
"'Five'",
6,
'7', # here list ends
@@ -209,10 +209,10 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- [(...,)], # means zero or MORE and so does match 2 texts
+ [...], # means zero or MORE and so does match 2 texts
"'Five'",
6,
'7',
@@ -221,47 +221,47 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- [(...,)], # means zero or MORE and so does match 2 texts
+ [...], # means zero or MORE and so does match 2 texts
"'Five'",
- ...,
- ...,
+ {...},
+ {...},
)
)
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- ...,
+ {...},
4,
"'Five'",
6,
- ..., # means exactly one and so does match 1 text
+ {...}, # means exactly one and so does match 1 text
)
)
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- ...,
+ {...},
4,
"'Five'",
6,
- (...,), # means one or more and so does match 1 text
+ ..., # means one or more and so does match 1 text
)
)
browser.all('li').should(
have.no._exact_texts_like(
- ..., # means exactly one and so does NOT match because of 2 texts (Zero, 1)
+ {...}, # means exactly one and does NOT match because of 2 texts (Zero, 1)
'Two',
- [(...,)], # means zero or MORE and so does match 2 texts
+ [...], # means zero or MORE and so does match 2 texts
"'Five'",
6,
'7',
@@ -270,9 +270,9 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- [(...,)], # means zero or more and so does match 2 texts at start
+ [...], # means zero or more and so does match 2 texts at start
'Two',
- ...,
+ {...},
4,
"'Five'",
6,
@@ -282,25 +282,25 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- ...,
+ {...},
4,
"'Five'",
6,
'7', # here list ends
- [(...,)], # means ZERO or more and so does match 0 texts
+ [...], # means ZERO or more and so does match 0 texts
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)], # means ZERO or more and so does match 0 texts
+ [...], # means ZERO or more and so does match 0 texts
'Zero', # here list STARTs
1,
'Two',
- ...,
+ {...},
4,
"'Five'",
6,
@@ -310,13 +310,13 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- ...,
+ {...},
4,
"'Five'",
- [(...,)], # means ZERO or more and so does match 0 texts
+ [...], # means ZERO or more and so does match 0 texts
6,
'7',
)
@@ -324,12 +324,12 @@ def test_exact_texts_like__with_default_exactly_one_and_zero_or_more(
browser.all('li').should(
have.no._exact_texts_like(
- ..., # means exactly one and so does NOT match
+ {...}, # means exactly one and so does NOT match
4,
"'Five'",
6,
'7',
- [(...,)],
+ [...],
)
)
@@ -355,75 +355,75 @@ def test_exact_texts_like__with_default_exactly_one_one_or_more_and_zero_or_more
browser.all('li').should(
have._exact_texts_like(
- (...,), # means zero or MORE and so does match 2 texts
+ ..., # means zero or MORE and so does match 2 texts
'Two',
- [(...,)],
+ [...],
"'Five'",
- ...,
+ {...},
'7',
)
)
browser.all('li').should(
have.no._exact_texts_like(
- (...,),
+ ...,
'Two',
- [(...,)],
+ [...],
"'Five'",
- ...,
- ..., # means zero or MORE and so does NOT match this absent text
+ {...},
+ {...}, # means zero or MORE and so does NOT match this absent text
'7',
)
)
browser.all('li').should(
have._exact_texts_like(
- ...,
- ...,
+ {...},
+ {...},
'Two',
- [(...,)],
+ [...],
"'Five'",
'6',
- (...,),
+ ...,
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
- ...,
+ {...},
+ {...},
"'Five'",
'6',
- (...,),
+ ...,
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
- ...,
+ {...},
+ {...},
"'Five'",
- [(...,)],
+ [...],
'6',
- (...,),
+ ...,
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
- ...,
+ {...},
+ {...},
"'Five'",
- [(...,)],
+ [...],
'6',
7,
- [(...,)],
+ [...],
)
)
@@ -450,102 +450,102 @@ def test_exact_texts_like__with_default_exactly_one_one_or_more_zero_or_more_zer
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...],
+ [{...}],
"'Five'",
- (...,),
+ ...,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...],
+ [{...}],
6,
- (...,),
+ ...,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...],
+ [{...}],
7,
- (...,),
+ ...,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Zero',
1,
'Two',
- ...,
+ {...},
4,
- [...],
+ [{...}],
"'Five'",
- (...,),
+ ...,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [...],
+ [{...}],
'Zero',
1,
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
- (...,),
+ ...,
8,
- [...],
+ [{...}],
)
)
browser.all('li').should(
have._exact_texts_like(
- [...],
+ [{...}],
1,
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
- (...,),
+ ...,
8,
- [...],
+ [{...}],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [...],
+ [{...}],
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
- (...,),
+ ...,
8,
[...],
)
@@ -553,30 +553,30 @@ def test_exact_texts_like__with_default_exactly_one_one_or_more_zero_or_more_zer
browser.all('li').should(
have._exact_texts_like(
- [...],
+ [{...}],
1,
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
6,
7,
- [...],
+ [{...}],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [...],
+ [{...}],
1,
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
6,
- [...],
+ [{...}],
)
)
@@ -603,175 +603,175 @@ def test_exact_texts_like__with_default_doubled_globs(
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # zero
- [...], # or two
+ [{...}], # zero
+ [{...}], # or two
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # zero
- [...], # or two
+ [{...}], # zero
+ [{...}], # or two
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # zero or one
- [...], # or two
+ [{...}], # zero or one
+ [{...}], # or two
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # zero or one
- [...], # or two
+ [{...}], # zero or one
+ [{...}], # or two
"'Five'",
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- ..., # one
- [...], # or two
+ {...}, # one
+ [{...}], # or two
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- ..., # one
- [...], # or two
+ {...}, # one
+ [{...}], # or two
"'Five'",
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- ..., # one
- [...], # or two
+ {...}, # one
+ [{...}], # or two
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- ..., # one
- [...], # or two
+ {...}, # one
+ [{...}], # or two
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # one
- ..., # or two
+ [{...}], # one
+ {...}, # or two
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # one
- ..., # or two
+ [{...}], # one
+ {...}, # or two
"'Five'",
6,
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # one
- ..., # or two
+ [{...}], # one
+ {...}, # or two
7,
8,
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._exact_texts_like(
- [(...,)],
+ [...],
'Two',
- ...,
+ {...},
4,
- [...], # one
- ..., # or two
+ [{...}], # one
+ {...}, # or two
8,
- [(...,)],
+ [...],
)
)
@@ -797,9 +797,9 @@ def test_exact_texts_like__where_overrides_original_globs(
)
browser.all('li').should(
- have.no._exact_texts_like(..., 'Two', ..., 4, "'Five'", 6, '7', [(...,)]).where(
- one_or_more=...
- )
+ have.no._exact_texts_like(
+ (...,), 'Two', (...,), 4, "'Five'", 6, '7', [...]
+ ).where(one_or_more=(...,))
)
@@ -822,9 +822,7 @@ def test_exact_texts_like__on__mixed_numbers_and_quoted_text__with_default_one_o
'''
)
- browser.all('li').should(
- have._exact_texts_like((...,), 'Two', (...,), 4, "'Five'", (...,))
- )
+ browser.all('li').should(have._exact_texts_like(..., 'Two', ..., 4, "'Five'", ...))
def test_exact_texts_like__on__mixed_numbers_emtpy_and_quoted_text(session_browser):
@@ -843,9 +841,7 @@ def test_exact_texts_like__on__mixed_numbers_emtpy_and_quoted_text(session_brows
'''
)
- browser.all('li').should(
- have._exact_texts_like(..., 'Two', ..., 4, "'Five'", ...).where(one_or_more=...)
- )
+ browser.all('li').should(have._exact_texts_like(..., 'Two', ..., 4, "'Five'", ...))
def test_exact_texts_like__on__mixed__with_expected_empty_text(session_browser):
@@ -864,9 +860,7 @@ def test_exact_texts_like__on__mixed__with_expected_empty_text(session_browser):
'''
)
- browser.all('li').should(
- have._exact_texts_like(0, ..., '', ..., "'Five'", ...).where(one_or_more=...)
- )
+ browser.all('li').should(have._exact_texts_like(0, ..., '', ..., "'Five'", ...))
def test_correct_exact_texts_like_exception_message_with_custom_globs(session_browser):
@@ -886,9 +880,7 @@ def test_correct_exact_texts_like_exception_message_with_custom_globs(session_br
)
try:
- browser.all('li').should(
- have._exact_texts_like(..., 'Two', '', ..., "'Five'").where(one_or_more=...)
- )
+ browser.all('li').should(have._exact_texts_like(..., 'Two', '', ..., "'Five'"))
pytest.fail('expected texts mismatch')
except AssertionError as error:
assert (
@@ -976,16 +968,16 @@ def test_correct_no_exact_texts_like_exception_message__with_custom_globs_mixed(
try:
browser.all('li').should(
have._exact_texts_like(
- [...],
+ [{...}],
1, # fails here: 1 != empty string
'Two',
- ...,
+ {...},
4,
- [(...,)],
+ [...],
"'Five'",
- (...,),
+ ...,
8,
- [...],
+ [{...}],
)
)
pytest.fail('expected texts mismatch')
@@ -995,7 +987,7 @@ def test_correct_no_exact_texts_like_exception_message__with_custom_globs_mixed(
'\n'
'Timed out after 0.1s, while waiting for:\n'
"browser.all(('css selector', 'li')).have exact texts like:\n"
- " [...], 1, Two, ..., 4, [(...,)]), 'Five', (...,), 8, [...]\n"
+ " [{...}], 1, Two, {...}, 4, [...]), 'Five', ..., 8, [{...}]\n"
'\n'
'Reason: AssertionError: actual visible texts:\n'
" Zero, , Two, , 4, 'Five', 6, 7, 8\n"
@@ -1028,7 +1020,7 @@ def test_correct_no_exact_texts_like_exception_message__with_default_globs(
try:
browser.all('li').should(
- have.no._exact_texts_like((...,), 'Two', '', (...,), "'Five'", 6)
+ have.no._exact_texts_like(..., 'Two', '', ..., "'Five'", 6)
)
pytest.fail('expected texts mismatch')
except AssertionError as error:
@@ -1037,7 +1029,7 @@ def test_correct_no_exact_texts_like_exception_message__with_default_globs(
'\n'
'Timed out after 0.1s, while waiting for:\n'
"browser.all(('css selector', 'li')).have no exact texts like:\n"
- " (...,), Two, , (...,), 'Five', 6\n"
+ " ..., Two, , ..., 'Five', 6\n"
'\n'
'Reason: AssertionError: actual visible texts:\n'
" Zero, , Two, , 4, 'Five', 6\n"
diff --git a/tests/integration/condition__collection__have_texts_like__with_items_globs_regex_patterns_and_wildcards_test.py b/tests/integration/condition__collection__have_texts_like__with_items_globs_regex_patterns_and_wildcards_test.py
index 8053c6ad..0fb4c51f 100644
--- a/tests/integration/condition__collection__have_texts_like__with_items_globs_regex_patterns_and_wildcards_test.py
+++ b/tests/integration/condition__collection__have_texts_like__with_items_globs_regex_patterns_and_wildcards_test.py
@@ -56,43 +56,43 @@ def test_text_patterns_like__mixed__with_regex_patterns_support(
# – for item texts in addition to support of ellipsis globs as items placeholders
browser.all('li').should(
match._text_patterns_like(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Thr.+.*?',
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
)
)
# with alias
browser.all('li').should(
have._text_patterns_like(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Thr.+.*?',
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
)
)
# with one more alias
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Thr.+.*?',
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
).with_regex
)
# without "_like" version will lack support of ellipsis globs as items placeholders
@@ -112,15 +112,15 @@ def test_text_patterns_like__mixed__with_regex_patterns_support(
)
browser.all('li').should(
match._text_patterns(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Thr.+.*?',
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
).not_
)
# with alias
@@ -166,15 +166,15 @@ def test_text_patternss_like__mixed__with_regex_patterns_support__error_messages
# – for item texts in addition to support of ellipsis globs as items placeholders
browser.all('li').should(
have._text_patterns_like(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Three', # fails on ending: 'Three' != 'Three...'
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
)
)
pytest.fail('expected texts mismatch')
@@ -184,8 +184,8 @@ def test_text_patternss_like__mixed__with_regex_patterns_support__error_messages
'\n'
'Timed out after 0.1s, while waiting for:\n'
"browser.all(('css selector', 'li')).have text patterns like:\n"
- ' [...], .*?O.e.*?, ..., .*?Three, (...,), .*?Six.*?, [(...,)]), '
- '.*?Ten.*?, [(...,)])\n'
+ ' [{...}], .*?O.e.*?, {...}, .*?Three, ..., .*?Six.*?, [...]), '
+ '.*?Ten.*?, [...])\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One..., 2) Two..., 3) Three..., 4) Four..., 5) Five..., 6) Six..., 7) '
@@ -203,15 +203,15 @@ def test_text_patternss_like__mixed__with_regex_patterns_support__error_messages
try:
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
r'.*?O.e.*?',
- ...,
+ {...},
r'.*?Three', # fails on ending: 'Three' != 'Three...'
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
).with_regex
)
pytest.fail('expected texts mismatch')
@@ -282,42 +282,42 @@ def test_text_patterns_like__mixed__with_implicit_wildcards_patterns_support(
# for the most common case (similar to classic have.texts)...
browser.all('li').should(
match._text_patterns_like(
- [...],
+ [{...}],
r'.*?One.*?',
- ...,
+ {...},
r'.*?Three.*?',
- (...,),
+ ...,
r'.*?Six.*?',
- [(...,)],
+ [...],
r'.*?Ten.*?',
- [(...,)],
+ [...],
)
)
# – there is a shortcut:
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'One',
- ...,
+ {...},
'Three',
- (...,),
+ ...,
'Six',
- [(...,)],
+ [...],
'Ten',
- [(...,)],
+ [...],
)
)
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'Two', # does NOT match: 'Two' != 'One'
- ...,
+ {...},
'Three',
- (...,),
+ ...,
'Six',
- [(...,)],
+ [...],
'Ten',
- [(...,)],
+ [...],
)
)
@@ -346,22 +346,22 @@ def test_texts_like__mixed__with_implicit_wildcards_patterns_support__with_error
try:
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'ONE', # fails here: 'ONE' != 'One'
- ...,
+ {...},
'Three',
- (...,),
+ ...,
'Six',
- [(...,)],
+ [...],
'Ten',
- [(...,)],
+ [...],
)
)
pytest.fail('expected texts mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts like:\n"
- ' [...], ONE, ..., Three, (...,), Six, [(...,)]), Ten, [(...,)])\n'
+ ' [{...}], ONE, {...}, Three, ..., Six, [...]), Ten, [...])\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One..., 2) Two..., 3) Three..., 4) Four..., 5) Five..., 6) Six..., 7) '
@@ -399,41 +399,41 @@ def test_texts_like__mixed__with_explicit_wildcards_patterns_support(
# .with_wildcards overrides default behavior
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'One', # does not match cause correct pattern '*One*' != 'One'
- ...,
+ {...},
'Three',
- (...,),
+ ...,
'Six',
- [(...,)],
+ [...],
'Ten',
- [(...,)],
+ [...],
).with_wildcards
)
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'*O?e*',
- ...,
+ {...},
'*T??ee*',
- (...,),
+ ...,
'*Six*',
- [(...,)],
+ [...],
'*Ten*',
- [(...,)],
+ [...],
).with_wildcards
)
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'*O?e*',
- ...,
+ {...},
'*T???ee*', # does not match: 'Three' != 'Th?ree'
- (...,),
+ ...,
'*Six*',
- [(...,)],
+ [...],
'*Ten*',
- [(...,)],
+ [...],
).with_wildcards
)
@@ -462,22 +462,22 @@ def test_texts_like__mixed__with_explicit_wildcards_patterns_support__with_error
try:
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'One', # does not match cause correct pattern '*One*' != 'One'
- ...,
+ {...},
'*T??ee*',
- (...,),
+ ...,
'*Six*',
- [(...,)],
+ [...],
'*Ten*',
- [(...,)],
+ [...],
).with_wildcards
)
pytest.fail('expected texts mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts with wildcards like:\n"
- ' [...], One, ..., *T??ee*, (...,), *Six*, [(...,)]), *Ten*, [(...,)])\n'
+ ' [{...}], One, {...}, *T??ee*, ..., *Six*, [...]), *Ten*, [...])\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One..., 2) Two..., 3) Three..., 4) Four..., 5) Five..., 6) Six..., 7) '
@@ -515,29 +515,29 @@ def test_texts_like__mixed__where_custom_wildcards_patterns_support(
# .with_wildcards customized overrides default (no-wildcards) behavior
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'One',
- ...,
+ {...},
'Three',
- (...,),
+ ...,
'Six',
- [(...,)],
+ [...],
'Ten',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**', exactly_one_char='_')
)
# .with_wildcards customized overrides default explicit-wildcards behavior
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'*O?e*',
- ...,
+ {...},
'*T??ee*',
- (...,),
+ ...,
'*Six*',
- [(...,)],
+ [...],
'*Ten*',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**', exactly_one_char='_')
)
# TODO: isn't it not obvious? the context is a bit different from .where...
@@ -548,42 +548,42 @@ def test_texts_like__mixed__where_custom_wildcards_patterns_support(
# even one overrides everything
browser.all('li').should(
have.no._texts_like(
- [...],
+ [{...}],
'**One**',
- ...,
+ {...},
'**T??ee**', # now are not considered as wildcards = does not match
- (...,),
+ ...,
'**Six**',
- [(...,)],
+ [...],
'**Ten**',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**')
)
# even one overrides everything
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'**One**',
- ...,
+ {...},
'**Three**', # now are not considered as wildcards = does not match
- (...,),
+ ...,
'**Six**',
- [(...,)],
+ [...],
'**Ten**',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**')
)
browser.all('li').should(
have._texts_like(
- [...],
+ [{...}],
'**O_e**',
- ...,
+ {...},
'**T__ee**',
- (...,),
+ ...,
'**Six**',
- [(...,)],
+ [...],
'**Ten**',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**', exactly_one_char='_')
)
@@ -612,15 +612,15 @@ def test_texts_like__mixed__where_custom_wildcards_patterns_support__with_errors
try:
browser.all('li').should(
have.no._texts_like( # fails here because actually matches without no
- [...],
+ [{...}],
'**O_e**',
- ...,
+ {...},
'**T__ee**',
- (...,),
+ ...,
'**Six**',
- [(...,)],
+ [...],
'**Ten**',
- [(...,)],
+ [...],
).where_wildcards(zero_or_more_chars='**', exactly_one_char='_')
)
pytest.fail('expected condition mismatch')
@@ -643,13 +643,13 @@ def test_texts_matching__regex_pattern__error__on_invalid_regex(session_browser)
)
try:
- browser.all('li').should(have._texts_like(r'*One.*', ..., ...).with_regex)
+ browser.all('li').should(have._texts_like(r'*One.*', {...}, {...}).with_regex)
pytest.fail('expected invalid regex error')
except AssertionError as error:
assert (
'Timed out after 0.1s, while waiting for:\n'
"browser.all(('css selector', 'li')).have text patterns like:\n"
- ' *One.*, ..., ...\n'
+ ' *One.*, {...}, {...}\n'
'\n'
'Reason: AssertionError: RegexError: nothing to repeat at position 1\n'
'actual visible texts:\n'
@@ -678,14 +678,14 @@ def test_texts_matching__regex_pattern__ignore_case_error__on_invalid_regex(
try:
browser.all('li').should(
- have._texts_like(r'*one.*', ..., ...).with_regex.ignore_case.not_
+ have._texts_like(r'*one.*', {...}, {...}).with_regex.ignore_case.not_
)
pytest.fail('expected invalid regex error')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no text patterns like (flags: "
're.IGNORECASE):\n'
- ' *one.*, ..., ...\n'
+ ' *one.*, {...}, {...}\n'
'\n'
'Reason: AssertionError: RegexError: nothing to repeat at position 1\n'
'actual visible texts:\n'
@@ -713,14 +713,14 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
)
# have.texts_like
- browser.all('li').should(have._texts_like('One', ..., ...))
+ browser.all('li').should(have._texts_like('One', {...}, {...}))
try:
- browser.all('li').should(have._texts_like('one', ..., ...))
+ browser.all('li').should(have._texts_like('one', {...}, {...}))
pytest.fail('expected text mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts like:\n"
- ' one, ..., ...\n'
+ ' one, {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -731,15 +731,15 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
' 1) One!!!‚2) Two...‚3) Three???‚\n'
) in str(error)
# - inverted
- browser.all('li').should(have.no._texts_like('one', ..., ...))
- browser.all('li').should(have._texts_like('one', ..., ...).not_)
+ browser.all('li').should(have.no._texts_like('one', {...}, {...}))
+ browser.all('li').should(have._texts_like('one', {...}, {...}).not_)
try:
- browser.all('li').should(have.no._texts_like('One', ..., ...))
+ browser.all('li').should(have.no._texts_like('One', {...}, {...}))
pytest.fail('expected mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no texts like:\n"
- ' One, ..., ...\n'
+ ' One, {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -750,16 +750,18 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
' 1) One!!!‚2) Two...‚3) Three???‚\n'
) in str(error)
# have._texts_like (ignore_case)
- browser.all('li').should(match._texts_like('one', ..., ..., _flags=re.IGNORECASE))
- browser.all('li').should(have._texts_like('one', ..., ...).ignore_case)
+ browser.all('li').should(
+ match._texts_like('one', {...}, {...}, _flags=re.IGNORECASE)
+ )
+ browser.all('li').should(have._texts_like('one', {...}, {...}).ignore_case)
try:
- browser.all('li').should(have._texts_like('one.', ..., ...).ignore_case)
+ browser.all('li').should(have._texts_like('one.', {...}, {...}).ignore_case)
pytest.fail('expected text mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts like (flags: "
're.IGNORECASE):\n'
- ' one., ..., ...\n'
+ ' one., {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -771,17 +773,19 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
) in str(error)
# - double inversion == no inversion
browser.all('li').should(
- match._texts_like('one', ..., ..., _flags=re.IGNORECASE).not_.not_
+ match._texts_like('one', {...}, {...}, _flags=re.IGNORECASE).not_.not_
)
- browser.all('li').should(have.no._texts_like('one', ..., ...).ignore_case.not_)
+ browser.all('li').should(have.no._texts_like('one', {...}, {...}).ignore_case.not_)
try:
- browser.all('li').should(have.no._texts_like('one.', ..., ...).ignore_case.not_)
+ browser.all('li').should(
+ have.no._texts_like('one.', {...}, {...}).ignore_case.not_
+ )
pytest.fail('expected text mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts like (flags: "
're.IGNORECASE):\n'
- ' one., ..., ...\n'
+ ' one., {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -793,15 +797,15 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
) in str(error)
# - inverted
# - - with no before
- browser.all('li').should(have.no._texts_like('one.', ..., ...).ignore_case)
+ browser.all('li').should(have.no._texts_like('one.', {...}, {...}).ignore_case)
try:
- browser.all('li').should(have.no._texts_like('one', ..., ...).ignore_case)
+ browser.all('li').should(have.no._texts_like('one', {...}, {...}).ignore_case)
pytest.fail('expected mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no texts like (flags: "
're.IGNORECASE):\n'
- ' one, ..., ...\n'
+ ' one, {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -813,15 +817,15 @@ def test_texts_like__including_ignorecase__passed_compared_to_failed(
) in str(error)
# - - with not after, in the end
# (in the middle works but without Autocomplete & not recommended)
- browser.all('li').should(have._texts_like('one.', ..., ...).ignore_case.not_)
+ browser.all('li').should(have._texts_like('one.', {...}, {...}).ignore_case.not_)
try:
- browser.all('li').should(have._texts_like('one', ..., ...).ignore_case.not_)
+ browser.all('li').should(have._texts_like('one', {...}, {...}).ignore_case.not_)
pytest.fail('expected mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no texts like (flags: "
're.IGNORECASE):\n'
- ' one, ..., ...\n'
+ ' one, {...}, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
diff --git a/tests/integration/condition__element__have_text_matching__compared_test.py b/tests/integration/condition__element__have_text_matching__compared_test.py
index 61d4bd54..1fc98a10 100644
--- a/tests/integration/condition__element__have_text_matching__compared_test.py
+++ b/tests/integration/condition__element__have_text_matching__compared_test.py
@@ -66,10 +66,12 @@ def test_text_matching__regex_pattern__compared(
browser.all('li').should(have.texts_matching(r'\d\) One!+', r'.*', r'.*'))
browser.all('li').should(have.texts_matching(r'\d\) One!+', r'.*', r'.*').not_.not_)
# that is also equivalent to:
- browser.all('li').should(have._texts_like(r'\d\) One(.)\1\1', ..., ...).with_regex)
+ browser.all('li').should(
+ have._texts_like(r'\d\) One(.)\1\1', {...}, {...}).with_regex
+ )
# or even:
browser.all('li').should(
- have._texts_like(r'\d\) One(.)\1\1', (...,)).with_regex # = one or more
+ have._texts_like(r'\d\) One(.)\1\1', ...).with_regex # = one or more
)
# And with smart approach you can mix to achieve more with less:
browser.all('li')[:3].should(have.text_matching(r'\d\) \w+(.)\1\1').each)
@@ -288,9 +290,10 @@ def test_text_matching__regex_pattern__ignore_case__compared(session_browser):
' 1) One!!!, 2) Two..., 3) Three???\n'
'\n'
'Pattern used for matching:\n'
- ' ^.*?One.*?‚.*?Two.*?‚[^‚]+‚$\n'
+ ' ^.*?One.*?‚.*?Two.*?‚.+?‚$\n'
'Actual text used to match:\n'
' 1) One!!!‚2) Two...‚3) Three???‚\n'
+ 'Screenshot: '
) in str(error)
diff --git a/tests/integration/condition__elements__have_text_and_co_test.py b/tests/integration/condition__elements__have_text_and_co_test.py
index 8f41c89b..9a50db53 100644
--- a/tests/integration/condition__elements__have_text_and_co_test.py
+++ b/tests/integration/condition__elements__have_text_and_co_test.py
@@ -289,7 +289,7 @@ def test_texts__including_ignorecase__passed_and_failed__compared_to_texts_like(
' 1) One!!!, 2) Two..., 3) Three???\n'
'\n'
'Pattern used for matching:\n'
- ' ^.*?one\\..*?‚.*?two\\..*?‚[^‚]+‚$\n'
+ ' ^.*?one\\..*?‚.*?two\\..*?‚.+?‚$\n'
'Actual text used to match:\n'
' 1) One!!!‚2) Two...‚3) Three???‚\n'
) in str(error)
@@ -297,12 +297,12 @@ def test_texts__including_ignorecase__passed_and_failed__compared_to_texts_like(
browser.all('li').with_(
_match_ignoring_case=True,
_match_only_visible_elements_texts=False,
- ).should(have._texts_like('one.', 'two.', ...))
+ ).should(have._texts_like('one.', 'two.', {...}))
pytest.fail('expected text mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have texts like (flags: re.IGNORECASE):\n"
- ' one., two., ...\n'
+ ' one., two., {...}\n'
'\n'
'Reason: AssertionError: actual texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -347,14 +347,14 @@ def test_texts__including_ignorecase__passed_and_failed__compared_to_texts_like(
) in str(error)
try:
browser.all('li').with_(_match_ignoring_case=True).should(
- have.no._texts_like('one', 'two', ...)
+ have.no._texts_like('one', 'two', {...})
)
pytest.fail('expected mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no texts like (flags: "
're.IGNORECASE):\n'
- ' one, two, ...\n'
+ ' one, two, {...}\n'
'\n'
'Reason: AssertionError: actual visible texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'
@@ -368,13 +368,13 @@ def test_texts__including_ignorecase__passed_and_failed__compared_to_texts_like(
browser.all('li').with_(
_match_ignoring_case=True,
_match_only_visible_elements_texts=False,
- ).should(have.no._texts_like('one', 'two', ...))
+ ).should(have.no._texts_like('one', 'two', {...}))
pytest.fail('expected mismatch')
except AssertionError as error:
assert (
"browser.all(('css selector', 'li')).have no texts like (flags: "
're.IGNORECASE):\n'
- ' one, two, ...\n'
+ ' one, two, {...}\n'
'\n'
'Reason: AssertionError: actual texts:\n'
' 1) One!!!, 2) Two..., 3) Three???\n'