Open yashaka opened 1 month ago
List of conditions added (still marked as experimental with _
prefix):
have._exact_texts_like(*exact_texts_or_list_globs: Union[str, int, float])
have._exact_texts_like(*exact_texts_or_list_globs: Union[str, int, float]).where(**globs_to_override)
have._texts_like(*contained_texts_or_list_globs: Union[str, int, float])
have._texts_like(*contained_texts_or_list_globs: Union[str, int, float]).where(**glob_to_override)
have._texts_like(*regex_patterns_or_list_globs: Union[str, int, float]).with_regex
have._text_patterns_like
have._text_patterns(*regex_patterns).with_regex
have.texts
but with regex patterns as expected, i.e. no list globs supporthave._texts_like(*texts_with_wildcards_or_list_globs: Union[str, int, float]).with_wildcards
have._texts_like(*texts_with_wildcards_or_list_globs: Union[str, int, float]).where_wildcards(**to_override)
have.no.*
versions of same conditionsWhere:
[...]
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^
(start of text) and $
(end of text)
because they are implicit, and if added explicitly will break the match*
matches zero or more of any characters in a text item?
matches exactly one of any character in a text itemWarning:
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 <li>1</li><li>2</li><li>Three</li><li>4</li><li>5</li>
in the list.Examples of usage:
from selene import browser, have
...
# GivenPage(browser.driver).opened_with_body(
# '''
# <ul>Hello:
# <li>1) One!!!</li>
# <li>2) Two!!!</li>
# <li>3) Three!!!</li>
# <li>4) Four!!!</li>
# <li>5) Five!!!</li>
# </ul>
# '''
# )
browser.all('li').should(have._exact_texts_like(
'1) One!!!', '2) Two!!!', ..., ..., ... # = exactly one
))
browser.all('li').should(have._texts_like(
'\d\) One!+', '\d.*', ..., ..., ...
).with_regex)
browser.all('li').should(have._texts_like(
'?) One*', '?) Two*', ..., ..., ...
).with_wildcards)
browser.all('li').should(have._texts_like(
'_) One**', '_) Two*', ..., ..., ...
).where_wildcards(zero_or_more='**', exactly_one='_'))
browser.all('li').should(have._texts_like(
'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'
))
browser.all('li').should(have._texts_like(
'One', ..., ..., 'Four', ... # = exactly one
))
browser.all('li').should(have._texts_like(
'One', 'Two', (..., ) # = one or more
))
browser.all('li').should(have._texts_like(
[(..., )], 'One', 'Two', [(..., )] # = ZERO or more ;)
))
browser.all('li').should(have._texts_like(
[...], 'One', 'Two', 'Three', 'Four', [...] # = zero or ONE ;)
))
# If you don't need so much "globs"...
# (here goes, actually, the 💡RECOMMENDED💡 way to use it in most cases...
# 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', ... # = zero OR MORE
).where(zero_or_more=...)) # – because the ... meaning was overridden
# Same works for other conditions that end with `_like`
browser.all('li').should(have._exact_texts_like(
..., '1) One!!!', '2) Two!!!', ...
).where(zero_or_more=...))
Here are the critique of previous globs:
...
?
...
somehow, for example by surrounding it with some "fences", and my first idea was to use ()
for that, but ()
forces to use coma so we get (...,)
that is not obvious as "exactly one", because 'coma' means that something will go after it :). That's why I had to choose (...,)
as "one or more", then keeping ...
as "exactly one". But why not to use {}
for "fencing"? then we don't have this "confusion with ,
meaning"!So, why not define default list globs as:
[{...}]
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 (consistent with numpy slicing style)[...]
matches zero or more items of any text in the listExamples of usage:
from selene import browser, have
...
# GivenPage(browser.driver).opened_with_body(
# '''
# <ul>Hello:
# <li>1) One!!!</li>
# <li>2) Two!!!</li>
# <li>3) Three!!!</li>
# <li>4) Four!!!</li>
# <li>5) Five!!!</li>
# </ul>
# '''
# )
browser.all('li').should(have._exact_texts_like(
'1) One!!!', '2) Two!!!', {...}, {...}, {...} # = exactly one
))
browser.all('li').should(have._texts_like(
'\d\) One!+', '\d.*', {...}, {...}, {...}
).with_regex)
browser.all('li').should(have._texts_like(
'?) One*', '?) Two*', {...}, {...}, {...}
).with_wildcards)
browser.all('li').should(have._texts_like(
'_) One**', '_) Two*', {...}, {...}, {...}
).where_wildcards(zero_or_more='**', exactly_one='_'))
browser.all('li').should(have._texts_like(
'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'
))
browser.all('li').should(have._texts_like(
'One', {...}, {...}, 'Four', {...} # = exactly one
))
browser.all('li').should(have._texts_like(
'One', 'Two', ... # = one or more
))
browser.all('li').should(have._texts_like(
[...], 'One', 'Two', [...] # = ZERO or more ;)
))
browser.all('li').should(have._texts_like(
[{...}], 'One', 'Two', 'Three', 'Four', [{...}] # = zero or ONE ;)
))
# If you don't need so much "globs"...
# (here goes, actually, the 💡RECOMMENDED💡 way to use it in most cases...
# 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(zero_or_more=...)) # – because the ... meaning was overridden
# Same works for other conditions that end with `_like`
browser.all('li').should(have._exact_texts_like(
..., '1) One!!!', '2) Two!!!', ...
).where(zero_or_more=...))
Something like: