Skip to content

Commit

Permalink
[#515] NEW: element.click with offset params
Browse files Browse the repository at this point in the history
  • Loading branch information
yashaka committed Mar 4, 2024
1 parent f600d39 commit 198d33f
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 9 deletions.
21 changes: 20 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,26 @@ TODOs:
- can we force order of how `selene.*` is rendered on autocomplete? via `__all__`...
- deprecate `have.js_returned` in favour of `have.script_returned`

## 2.0.0rc8 (to be released on 03.03.2024)
## 2.0.0rc8 (to be released on 04.03.2024)

### Click with offsets

As simple as that:

```python
from selene import browser, command

...

browser.element('#point1').click(xoffset=-5, yoffset=5) # relative from center
browser.element('#point1').click() # still works as before (clicking at center)
# with js too:
browser.element('#point1').perform(command.js.click(xoffset=-5, yoffset=5))
browser.element('#point1').perform(command.js.click()) # also works
browser.element('#point1').perform(command.js.click) # still works as before
# or:
browser.element('#point1').with_(click_by_js=True).click(xoffset=-5, yoffset=5)
```

### Smarter command.select_all

Expand Down
30 changes: 24 additions & 6 deletions selene/core/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,19 +517,37 @@ def fn(element: Element):

return self

# TODO: add offset args with defaults, or add additional method, think on what is better
def click(self) -> Element:
"""Just a normal click:)"""
# TODO: consider support of percentage in offsets (in command.js.click too)
def click(self, *, xoffset=0, yoffset=0) -> Element:
"""Just a normal click with optional offset:)"""

def raw_click(element: Element):
element.locate().click()

def click_with_offset_actions(element: Element):
actions: ActionChains = ActionChains(self.config.driver)
webelement = (
element._actual_not_overlapped_webelement
if self.config.wait_for_no_overlap_found_by_js
else element.locate()
)
actions.move_to_element_with_offset(
webelement, xoffset, yoffset
).click().perform()

from selene.core import command

self.wait.for_(
typing.cast(Command[Element], command.js.click)
command.js.click(xoffset=xoffset, yoffset=yoffset)
if self.config.click_by_js
else Command('click', raw_click)
else (
Command('click', raw_click)
if (not xoffset and not yoffset)
else Command(
f'click(xoffset={xoffset},yoffset={yoffset})',
click_with_offset_actions,
)
)
)

return self
Expand All @@ -541,7 +559,7 @@ def fn(element: Element):
webelement = (
element._actual_not_overlapped_webelement
if self.config.wait_for_no_overlap_found_by_js
else element()
else element.locate()
)
actions.double_click(webelement).perform()

Expand Down
2 changes: 1 addition & 1 deletion selene/core/entity.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class Element(WaitingEntity['Element']):
def press_tab(self) -> Element: ...
def clear(self) -> Element: ...
def submit(self) -> Element: ...
def click(self) -> Element: ...
def click(self, *, xoffset=0, yoffset=0) -> Element: ...
def double_click(self) -> Element: ...
def context_click(self) -> Element: ...
def hover(self) -> Element: ...
Expand Down
17 changes: 17 additions & 0 deletions tests/integration/element__click_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import time

from selene import have
from tests.integration.helpers.givenpage import GivenPage


Expand Down Expand Up @@ -42,3 +44,18 @@ def test_click_waits_for_no_overlay(session_browser):
time_diff = time.time() - before_call
assert 0.25 < time_diff < 0.5
assert "second" in browser.driver.current_url


# TODO: cover yoffset too
def test_command_js_click__with_xoffset(session_browser):
browser = session_browser.with_(timeout=0.5)
page = GivenPage(browser.driver)
page.opened_with_body(
'''
<input type="range" min="0.0" max="5.0" step="0.5" value="0">
'''
)

browser.element('input').click(xoffset=-10)

browser.element('input').should(have.value('2'))
17 changes: 16 additions & 1 deletion tests/integration/element__perform__js__click_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time

from selene import command
from selene import command, query, have
from tests.integration.helpers.givenpage import GivenPage


Expand Down Expand Up @@ -86,3 +86,18 @@ def test_command_js_click__call__is_still_same_command(session_browser):
time_diff = time.time() - before_call
assert time_diff < 0.25
assert "second" in browser.driver.current_url


def x_test_command_js_click__with_offset(session_browser):
browser = session_browser.with_(timeout=0.5)
page = GivenPage(browser.driver)
page.opened_with_body(
'''
<input type="range" min="0.0" max="5.0" step="0.5" value="0">
'''
)

# TODO: why it does not click on slider? o_O
browser.element('input').perform(command.js.click(xoffset=-10))

browser.element('input').should(have.value('2'))

0 comments on commit 198d33f

Please sign in to comment.