Skip to content

Commit cf814bf

Browse files
authored
Merge pull request #145 from autoscrape-labs/fix/type-text
fix: click in the input before typing and fix documentation
2 parents 41abe79 + c930289 commit cf814bf

File tree

9 files changed

+18
-11
lines changed

9 files changed

+18
-11
lines changed

docs/api/commands/dom.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ The DOM commands module provides functions for:
5555
- `request_child_nodes()` - Get child elements
5656

5757
!!! tip "High-Level APIs"
58-
While these commands provide powerful low-level access, most users should use the higher-level `WebElement` class methods like `click()`, `type()`, and `get_attribute()` which use these commands internally.
58+
While these commands provide powerful low-level access, most users should use the higher-level `WebElement` class methods like `click()`, `type_text()`, and `get_attribute()` which use these commands internally.

docs/api/commands/input.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,4 @@ The input commands support human-like behavior patterns:
7272
- Pressure-sensitive touch events
7373

7474
!!! tip "Element Methods"
75-
For most use cases, use the higher-level element methods like `element.click()` and `element.type()` which provide a more convenient API and handle common scenarios automatically.
75+
For most use cases, use the higher-level element methods like `element.click()` and `element.type_text()` which provide a more convenient API and handle common scenarios automatically.

docs/deep-dive/browser-domain.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,8 @@ async def test_multiple_accounts():
385385
tab = await browser.new_tab("https://app.example.com/login", browser_context_id=context_id)
386386

387387
# Login with account credentials
388-
await tab.find(tag_name="input", name="username").type(account["username"])
389-
await tab.find(tag_name="input", name="password").type(account["password"])
388+
await tab.find(tag_name="input", name="username").type_text(account["username"])
389+
await tab.find(tag_name="input", name="password").type_text(account["password"])
390390
await tab.find(tag_name="button", type="submit").click()
391391

392392
contexts_and_tabs.append((context_id, tab, account["username"]))

docs/deep-dive/event-system.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ await tab.enable_page_events()
662662
async def handle_page_load(tab, event):
663663
print(f"Page loaded: {await tab.current_url}")
664664
# Perform actions after page load
665-
await tab.find(id="search").type("pydoll")
665+
await tab.find(id="search").type_text("pydoll")
666666

667667
await tab.on(PageEvent.LOAD_EVENT_FIRED, partial(handle_page_load, tab))
668668

docs/deep-dive/find-elements-mixin.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,10 @@ Found elements are returned as WebElement instances that provide rich interactio
652652
```python
653653
# Find and interact with form elements
654654
username = await tab.find(name="username")
655-
await username.type("[email protected]")
655+
await username.type_text("[email protected]")
656656

657657
password = await tab.find(type="password")
658-
await password.type("secretpassword")
658+
await password.type_text("secretpassword")
659659

660660
submit = await tab.find(tag_name="button", type="submit")
661661
await submit.click()

docs/deep-dive/tab-domain.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,8 @@ tab3 = await browser.new_tab("https://github.com")
507507

508508
# Work with different tabs
509509
await tab1.go_to("https://google.com")
510-
await tab2.find(id="search").type("Pydoll")
511-
await tab3.find(class_name="header-search-input").type("automation")
510+
await tab2.find(id="search").type_text("Pydoll")
511+
await tab3.find(class_name="header-search-input").type_text("automation")
512512

513513
# Close specific tabs when done
514514
await tab2.close()

docs/features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ async def iframe_interaction():
487487

488488
# You can use all Tab methods on the frame
489489
form_input = await frame.find(id='captcha-input')
490-
await form_input.type('verification-code')
490+
await form_input.type_text('verification-code')
491491

492492
# Find elements by various methods
493493
links = await frame.find(tag_name='a', find_all=True)

pydoll/elements/web_element.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ async def type_text(self, text: str, interval: float = 0.1):
287287
288288
More realistic than insert_text() but slower.
289289
"""
290+
await self.click()
290291
for char in text:
291292
await self._execute_command(
292293
InputCommands.dispatch_key_event(

tests/test_web_element.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,13 @@ async def test_insert_text(self, input_element):
291291
async def test_type_text(self, input_element):
292292
"""Test type_text method with character-by-character typing."""
293293
test_text = 'Hi'
294+
input_element.click = AsyncMock()
294295
with patch('asyncio.sleep') as mock_sleep:
295296
await input_element.type_text(test_text, interval=0.05)
296297

297298
# Should call execute_command for each character
298299
assert input_element._connection_handler.execute_command.call_count == len(test_text)
300+
assert input_element.click.call_count == 1
299301

300302
# Verify sleep was called between characters
301303
assert mock_sleep.call_count == len(test_text)
@@ -305,10 +307,12 @@ async def test_type_text(self, input_element):
305307
async def test_type_text_default_interval(self, input_element):
306308
"""Test type_text with default interval."""
307309
test_text = 'A'
310+
input_element.click = AsyncMock()
308311
with patch('asyncio.sleep') as mock_sleep:
309312
await input_element.type_text(test_text)
310313

311314
mock_sleep.assert_called_with(0.1) # Default interval
315+
assert input_element.click.call_count == 1
312316

313317

314318
class TestWebElementKeyboardInteraction:
@@ -878,10 +882,12 @@ async def test_click_with_zero_hold_time(self, web_element):
878882
@pytest.mark.asyncio
879883
async def test_type_text_empty_string(self, input_element):
880884
"""Test type_text with empty string."""
885+
input_element.click = AsyncMock()
881886
await input_element.type_text('')
882-
887+
883888
# Should not call execute_command for empty string
884889
input_element._connection_handler.execute_command.assert_not_called()
890+
assert input_element.click.call_count == 1
885891

886892
@pytest.mark.asyncio
887893
async def test_set_input_files_empty_list(self, file_input_element):

0 commit comments

Comments
 (0)