Skip to content

Commit

Permalink
[#530] REFACTOR: rename config._ignore_case ...
Browse files Browse the repository at this point in the history
... to config._match_ignoring_case because browser.with(_ignore_case=True).element(by.text(...)) will confuse...
  • Loading branch information
yashaka committed Jul 17, 2024
1 parent 8cb7098 commit d4222d9
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 245 deletions.
1 change: 1 addition & 0 deletions .pylint-disabled-rules
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ unused-private-member,
typevar-name-incorrect-variance,
anomalous-backslash-in-string,
use-dict-literal,
too-many-statements,
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,12 @@ browser.all('li').first.should(have.text_matching(r'.*one.*').where_flags(re.IGN

```

Same can be achieved via `_ignore_case` config option (yet marked as experimental):
Same can be achieved via `_match_ignoring_case` config option (yet marked as experimental):

```python
from selene import browser, have
...
browser.all('li').first.with_(_ignore_case=True).should(have.exact_text('1) one!!!'))
browser.all('li').first.with_(_match_ignoring_case=True).should(have.exact_text('1) one!!!'))

# and so on for other conditions that support ignore_case as property...
...
Expand Down
382 changes: 203 additions & 179 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ skip-string-normalization = 1
use-symbolic-message-instead,
typevar-name-incorrect-variance,
anomalous-backslash-in-string,
too-many-statements,
use-dict-literal''']
[tool.pylint.'REPORTS']
evaluation=['10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)']
Expand Down
2 changes: 1 addition & 1 deletion selene/core/_browser.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class Browser(WaitingEntity['Browser']):
wait_for_no_overlap_found_by_js: bool = False,
_match_only_visible_elements_texts: bool = True,
_match_only_visible_elements_size: bool = False,
_ignore_case: bool = False,
_match_ignoring_case: bool = False,
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...,
) -> Browser: ...
Expand Down
6 changes: 5 additions & 1 deletion selene/core/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1159,8 +1159,12 @@ def _executor(self):
# - does not explicitly tell that relates only to matching
# * but... it should be kind of obvious that can be used only in context of matching
# * and actually it's consistent with have.*.ignore_case conditions
# - ! it will confuse in the following context:
# > browser.with(ignore_case=True).element(by.text('submit')).click()
# as we might start think that the search by text will be done ignoring case
# but it will not :(
# todo: consider documenting the major list of conditions that are affected by this option
_ignore_case: bool = False
_match_ignoring_case: bool = False

# TODO: better name? now technically it's not a decorator but decorator_builder...
# or decorator_factory...
Expand Down
6 changes: 3 additions & 3 deletions selene/core/configuration.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class Config:
wait_for_no_overlap_found_by_js: bool = False
_match_only_visible_elements_texts: bool = True
_match_only_visible_elements_size: bool = False
_ignore_case: bool = False
_match_ignoring_case: bool = False
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...
_executor: _DriverStrategiesExecutor = ...
Expand Down Expand Up @@ -157,7 +157,7 @@ class Config:
wait_for_no_overlap_found_by_js: bool = False,
_match_only_visible_elements_texts: bool = True,
_match_only_visible_elements_size: bool = False,
_ignore_case: bool = False,
_match_ignoring_case: bool = False,
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...,
): ...
Expand Down Expand Up @@ -213,7 +213,7 @@ class Config:
wait_for_no_overlap_found_by_js: bool = False,
_match_only_visible_elements_texts: bool = True,
_match_only_visible_elements_size: bool = False,
_ignore_case: bool = False,
_match_ignoring_case: bool = False,
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...,
): ...
4 changes: 2 additions & 2 deletions selene/core/entity.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class Element(WaitingEntity['Element']):
wait_for_no_overlap_found_by_js: bool = False,
_match_only_visible_elements_texts: bool = True,
_match_only_visible_elements_size: bool = False,
_ignore_case: bool = False,
_match_ignoring_case: bool = False,
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...,
) -> Element: ...
Expand Down Expand Up @@ -152,7 +152,7 @@ class Collection(WaitingEntity['Collection'], Iterable[Element]):
wait_for_no_overlap_found_by_js: bool = False,
_match_only_visible_elements_texts: bool = True,
_match_only_visible_elements_size: bool = False,
_ignore_case: bool = False,
_match_ignoring_case: bool = False,
# Etc.
_build_wait_strategy: Callable[[Config], Callable[[E], Wait[E]]] = ...,
) -> Collection: ...
Expand Down
26 changes: 16 additions & 10 deletions selene/core/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def __init__(
name
+ (
' ignoring case:'
if (maybe_entity is not None and maybe_entity.config._ignore_case)
if (
maybe_entity is not None
and maybe_entity.config._match_ignoring_case
)
or _ignore_case
else ''
)
Expand All @@ -101,7 +104,7 @@ def __init__(
if (
entity_and_actual[0],
actual := entity_and_actual[1],
)[0].config._ignore_case
)[0].config._match_ignoring_case
or _ignore_case
else by(str(expected))(str(actual))
),
Expand Down Expand Up @@ -162,7 +165,7 @@ def compare(entity_and_actual: Tuple[Collection, Iterable]) -> bool:
str_lower = lambda some: str(some).lower()
return (
by(map(str_lower, expected_flattened))(map(str_lower, actual))
if entity.config._ignore_case or _ignore_case
if entity.config._match_ignoring_case or _ignore_case
else by(map(str, expected_flattened))(map(str, actual))
)

Expand All @@ -171,7 +174,10 @@ def compare(entity_and_actual: Tuple[Collection, Iterable]) -> bool:
name
+ (
' ignoring case:'
if (maybe_entity is not None and maybe_entity.config._ignore_case)
if (
maybe_entity is not None
and maybe_entity.config._match_ignoring_case
)
or _ignore_case
else ''
)
Expand Down Expand Up @@ -458,14 +464,14 @@ def __init__(self, expected: str, _flags=0, _inverted=False):

super().__init__(
lambda maybe_entity: (
f'has text matching'
'has text matching'
+ (
f' (with flags {flags}):'
if (
flags := (
_flags | re.IGNORECASE
if maybe_entity is not None
and maybe_entity.config._ignore_case
and maybe_entity.config._match_ignoring_case
else _flags
)
)
Expand All @@ -479,7 +485,7 @@ def __init__(self, expected: str, _flags=0, _inverted=False):
(
_flags | re.IGNORECASE
if entity_and_actual[0] is not None
and entity_and_actual[0].config._ignore_case
and entity_and_actual[0].config._match_ignoring_case
else _flags
),
)(entity_and_actual[1]),
Expand Down Expand Up @@ -1167,7 +1173,7 @@ def __call__(self, entity: Collection):
actual_to_match,
(
self._flags | re.IGNORECASE
if entity.config._ignore_case
if entity.config._match_ignoring_case
else self._flags
),
)
Expand All @@ -1183,7 +1189,7 @@ def describe_not_match():
# for item in self._expected
# ]
return (
f'actual '
'actual '
+ (
'visible '
if entity.config._match_only_visible_elements_texts
Expand Down Expand Up @@ -1245,7 +1251,7 @@ def __str__(self):
def _name_for(self, entity: Collection | None = None) -> str:
return (
self.ignore_case.__str__()
if entity is not None and entity.config._ignore_case
if entity is not None and entity.config._match_ignoring_case
else self.__str__()
)

Expand Down
8 changes: 6 additions & 2 deletions tests/integration/condition__browser__have_url_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ def test_have_url_containing__ignore_case(session_browser):
) in str(error)
assert re.findall(r'file:.*empty\.html\n', str(error))
try:
browser.with_(_ignore_case=True).should(have.url_containing('NONEMPTY.html'))
browser.with_(_match_ignoring_case=True).should(
have.url_containing('NONEMPTY.html')
)
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -74,7 +76,9 @@ def test_have_url_containing__ignore_case(session_browser):
) in str(error)
assert re.findall(r'file:.*empty\.html\n', str(error))
try:
browser.with_(_ignore_case=True).should(have.no.url_containing('EMPTY.html'))
browser.with_(_match_ignoring_case=True).should(
have.no.url_containing('EMPTY.html')
)
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand Down
51 changes: 32 additions & 19 deletions tests/integration/condition__element__have_exact_text_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def test_should_have_exact_text__passed_and_failed__with_text_to_trim__ignore_ca
s('#visible').should(have.exact_text('ONE !!!').ignore_case)
s('#visible').should(have.exact_text('ONE !!!').ignore_case.not_.not_)
s('#visible').should(have.no.exact_text('ONE !!!').ignore_case.not_)
s('#visible').with_(_ignore_case=True).should(have.exact_text('ONE !!!'))
s('#visible').with_(_match_ignoring_case=True).should(have.exact_text('ONE !!!'))
# - visible and incorrect expected (partial) fails
try:
s('#visible').should(have.exact_text('ONE').ignore_case)
Expand All @@ -157,7 +157,7 @@ def test_should_have_exact_text__passed_and_failed__with_text_to_trim__ignore_ca
'Reason: ConditionMismatch: actual text: One !!!\n'
) in str(error)
try:
s('#visible').with_(_ignore_case=True).should(have.exact_text('ONE'))
s('#visible').with_(_match_ignoring_case=True).should(have.exact_text('ONE'))
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -170,17 +170,17 @@ def test_should_have_exact_text__passed_and_failed__with_text_to_trim__ignore_ca
s('#visible-empty').should(have.exact_text('').ignore_case)
s('#visible-empty').should(have.exact_text('').ignore_case.not_.not_)

s('#visible-empty').with_(_ignore_case=True).should(have.exact_text(''))
s('#visible-empty').with_(_match_ignoring_case=True).should(have.exact_text(''))
# - visible & non-textable (like input) with always '' expected passes
'''
# let's just skip it:)
'''
# - hidden and with always '' expected passes
s('#hidden').should(have.exact_text('').ignore_case)
s('#hidden').with_(_ignore_case=True).should(have.exact_text(''))
s('#hidden').with_(_match_ignoring_case=True).should(have.exact_text(''))
# - hidden & empty with always '' expected passes
s('#hidden-empty').should(have.exact_text('').ignore_case)
s('#hidden-empty').with_(_ignore_case=True).should(have.exact_text(''))
s('#hidden-empty').with_(_match_ignoring_case=True).should(have.exact_text(''))
# - hidden and incorrect expected of actual exact text fails
'''
# let's just skip it:)
Expand All @@ -198,7 +198,7 @@ def test_should_have_exact_text__passed_and_failed__with_text_to_trim__ignore_ca
'{"method":"css selector","selector":"#absent"}\n'
) in str(error)
try:
s('#absent').with_(_ignore_case=True).should(have.exact_text(''))
s('#absent').with_(_match_ignoring_case=True).should(have.exact_text(''))
pytest.fail('expect failure')
except AssertionError as error:
assert (
Expand All @@ -221,7 +221,9 @@ def test_should_have_exact_text__passed_and_failed__with_text_to_trim__ignore_ca
'{"method":"css selector","selector":"#absent"}\n'
) in str(error)
try:
s('#absent').with_(_ignore_case=True).should(have.exact_text('').not_.not_)
s('#absent').with_(_match_ignoring_case=True).should(
have.exact_text('').not_.not_
)
pytest.fail('expect failure')
except AssertionError as error:
assert (
Expand Down Expand Up @@ -386,18 +388,24 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
s('#visible').should(match.exact_text(' ONE !!!\n').ignore_case.not_)
s('#visible').should(have.no.exact_text(' ONE !!!\n').ignore_case)
s('#visible').should(have.no.exact_text(' ONE !!!\n').ignore_case.not_.not_)
s('#visible').with_(_ignore_case=True).should(match.exact_text(' ONE !!!\n').not_)
s('#visible').with_(_ignore_case=True).should(have.no.exact_text(' ONE !!!\n'))
s('#visible').with_(_ignore_case=True).should(
s('#visible').with_(_match_ignoring_case=True).should(
match.exact_text(' ONE !!!\n').not_
)
s('#visible').with_(_match_ignoring_case=True).should(
have.no.exact_text(' ONE !!!\n')
)
s('#visible').with_(_match_ignoring_case=True).should(
have.no.exact_text(' ONE !!!\n').not_.not_
)
# - visible and incorrect expected (partial) passes
s('#visible').should(match.exact_text('ONE').ignore_case.not_)
s('#visible').should(have.no.exact_text('ONE').ignore_case)
s('#visible').should(have.no.exact_text('ONE').ignore_case.not_.not_)
s('#visible').with_(_ignore_case=True).should(match.exact_text('ONE').not_)
s('#visible').with_(_ignore_case=True).should(have.no.exact_text('ONE'))
s('#visible').with_(_ignore_case=True).should(have.no.exact_text('ONE').not_.not_)
s('#visible').with_(_match_ignoring_case=True).should(match.exact_text('ONE').not_)
s('#visible').with_(_match_ignoring_case=True).should(have.no.exact_text('ONE'))
s('#visible').with_(_match_ignoring_case=True).should(
have.no.exact_text('ONE').not_.not_
)
# - visible and correct expected (normalized) fails
try:
s('#visible').should(have.no.exact_text('ONE !!!').ignore_case)
Expand All @@ -410,7 +418,9 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
'Reason: ConditionMismatch: actual text: One !!!\n'
) in str(error)
try:
s('#visible').with_(_ignore_case=True).should(have.no.exact_text('ONE !!!'))
s('#visible').with_(_match_ignoring_case=True).should(
have.no.exact_text('ONE !!!')
)
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -431,7 +441,9 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
'Reason: ConditionMismatch: actual text: \n'
) in str(error)
try:
s('#visible-empty').with_(_ignore_case=True).should(have.no.exact_text(''))
s('#visible-empty').with_(_match_ignoring_case=True).should(
have.no.exact_text('')
)
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -456,8 +468,7 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
'Reason: ConditionMismatch: actual text: \n'
) in str(error)
try:
s('#hidden').with_(_ignore_case=True).should(have.no.exact_text(''))
s('#hidden').with_(ignore_case=True).should(have.no.exact_text(''))
s('#hidden').with_(_match_ignoring_case=True).should(have.no.exact_text(''))
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -478,7 +489,9 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
'Reason: ConditionMismatch: actual text: \n'
) in str(error)
try:
s('#hidden-empty').with_(_ignore_case=True).should(have.no.exact_text(''))
s('#hidden-empty').with_(_match_ignoring_case=True).should(
have.no.exact_text('')
)
pytest.fail('expect mismatch')
except AssertionError as error:
assert (
Expand All @@ -504,7 +517,7 @@ def test_should_have_no_exact_text__passed_and_failed__with_text_to_trim__ignore
'{"method":"css selector","selector":"#absent"}\n'
) in str(error)
try:
s('#absent').with_(_ignore_case=True).should(have.no.exact_text(''))
s('#absent').with_(_match_ignoring_case=True).should(have.no.exact_text(''))
pytest.fail('expect failure')
except AssertionError as error:
assert (
Expand Down
Loading

0 comments on commit d4222d9

Please sign in to comment.