Skip to content

Commit 5f0d5a3

Browse files
atthaboonpenploy
andauthored
Update keywords document v0.3 (#8)
* setup_document added documents * setup_documents add new doc for waiting keyword #1 * setup_document add document for waiting keyword #2 * Update quck start doc * Clanup doc Co-authored-by: Penploy <penploy.s@gmail.com>
1 parent 64a0b3f commit 5f0d5a3

File tree

10 files changed

+231
-42
lines changed

10 files changed

+231
-42
lines changed

Examples/quick-start.robot

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ Example login form submit
1111
Maximize Browser Window
1212
Input text id:username_field demo
1313
Input text id:password_field mode
14-
Click Element id:login_button
14+
Run Async Keywords
15+
... Click Element id:login_button AND
16+
... Wait For Response Url http://127.0.0.1:7272/welcome.html
1517
Wait Until Page Contains Login succeeded
1618
# Logout and wait for homepage loaded
1719
Run Async Keywords

PuppeteerLibrary/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ class PuppeteerLibrary(DynamicCore):
3636
| link | Exact text a link has. | ``link:Home page`` |
3737
| partial link | Partial link text | ``partial link:Home`` |
3838
39-
== Asynchronous Handler ==
40-
Core functionality for
41-
4239
"""
4340

4441
ROBOT_LIBRARY_SCOPE = 'GLOBAL'

PuppeteerLibrary/keywords/browsermanagement.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def open_browser(self, url, browser="chrome", alias=None, options=None):
2626
2727
Example:
2828
29-
| &{options} = | create dictionary | headless=${False} |
30-
| Open browser | https://www.w3schools.com/html/html_forms.asp | options=${options} |
29+
| &{options} = | create dictionary | headless=${False} |
30+
| `Open browser` | https://www.w3schools.com/html/html_forms.asp | options=${options} |
3131
3232
"""
3333
async def open_browser_async():
@@ -104,6 +104,14 @@ async def reload_page_async():
104104

105105
@keyword
106106
def wait_for_new_window_open(self, timeout=5):
107+
"""
108+
Waits until new page or tab opens.
109+
110+
Example:
111+
112+
| Run Async Keywords | Click Element | id:view_conditions | AND |
113+
| ... | `Wait For New Window Open` | | |
114+
"""
107115
async def wait_for_new_page_open_async():
108116
pages = await self.ctx.get_browser().pages()
109117
await pages[-1].title() # workaround for force pages re-cache

PuppeteerLibrary/keywords/element.py

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,61 @@ def __init__(self, ctx):
1010
self.async_func = ElementKeywordsAsync(self.ctx)
1111

1212
@keyword
13-
def click_element(self, selenium_locator):
14-
return self.loop.run_until_complete(self.async_func.click_element_async(selenium_locator))
13+
def click_element(self, locator):
14+
"""Clicks element identified by ``locator``.
15+
16+
Example:
17+
18+
| `Click Element` | id:register |
19+
"""
20+
return self.loop.run_until_complete(self.async_func.click_element_async(locator))
1521

1622
@keyword
17-
def click_link(self, selenium_locator):
18-
return self.loop.run_until_complete(self.async_func.click_link_async(selenium_locator))
23+
def click_link(self, locator):
24+
"""Clicks link identified by ``locator``.
25+
26+
Example:
27+
28+
| `Click Link` | id:view_more |
29+
"""
30+
return self.loop.run_until_complete(self.async_func.click_link_async(locator))
1931

2032
@keyword
21-
def click_button(self, selenium_locator):
22-
self.loop.run_until_complete(self.async_func.click_button_async(selenium_locator))
33+
def click_button(self, locator):
34+
"""Clicks button identified by ``locator``.
35+
36+
Example:
37+
38+
| `Click Button` | id:submit |
39+
"""
40+
self.loop.run_until_complete(self.async_func.click_button_async(locator))
2341

2442
@keyword
25-
def click_image(self, selenium_locator):
26-
self.loop.run_until_complete(self.async_func.click_image_async(selenium_locator))
43+
def click_image(self, locator):
44+
"""Clicks image identified by ``locator``.
45+
46+
Example:
47+
48+
| `Click Image` | id:cat_image |
49+
"""
50+
self.loop.run_until_complete(self.async_func.click_image_async(locator))
2751

2852
@keyword
29-
def get_text(self, selenium_locator):
30-
return self.loop.run_until_complete(self.async_func.get_text_async(selenium_locator))
53+
def get_text(self, locator):
54+
"""Returns text value of element identified by ``locator``.
55+
56+
Example:
57+
58+
| ${text} | `Get Text` | id:username |
59+
"""
60+
return self.loop.run_until_complete(self.async_func.get_text_async(locator))
3161

3262
@keyword
33-
def get_value(self, selenium_locator):
34-
return self.loop.run_until_complete(self.async_func.get_text_async(selenium_locator))
63+
def get_value(self, locator):
64+
"""Returns specific attribute value of element identified by ``locator``.
65+
66+
Example:
67+
68+
| ${value} | `Get Value` | id:comment |
69+
"""
70+
return self.loop.run_until_complete(self.async_func.get_text_async(locator))

PuppeteerLibrary/keywords/formelement.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,26 @@ def __init__(self, ctx):
1010
self.async_func = FormElementKeywordsAsync(self.ctx)
1111

1212
@keyword
13-
def input_text(self, selenium_locator, text, clear=True):
14-
self.loop.run_until_complete(self.async_func.input_text_async(selenium_locator, text, clear))
13+
def input_text(self, locator, text, clear=True):
14+
"""Types the given text into text field identified by ``locator``.
15+
16+
If clear is true, the input element will be cleared before the text is typed into the element.
17+
On the other hand clear is false, the previous text will not be cleared from the element.
18+
19+
Examples:
20+
| `Input Text` | id:name | John Doe | |
21+
| `Input Text` | id:username | john | True |
22+
23+
"""
24+
self.loop.run_until_complete(self.async_func.input_text_async(locator, text, clear))
1525

1626
@keyword
17-
def clear_element_text(self, selenium_locator):
18-
self.loop.run_until_complete(self.async_func.clear_element_text_async(selenium_locator))
27+
def clear_element_text(self, locator):
28+
"""Clears value of text field identified by ``locator``.
29+
30+
Example:
31+
32+
| `Clear Element Text` | id:name |
33+
"""
34+
self.loop.run_until_complete(self.async_func.clear_element_text_async(locator))
1935

PuppeteerLibrary/keywords/utility.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@ class UtilityKeywords(LibraryComponent):
99
@keyword
1010
def run_async_keywords(self, *keywords):
1111
# Ensure that script load async keywords before run async keywords function
12+
"""Executes all the given keywords in a asynchronous and wait until all keyword is completed
13+
14+
Example:
15+
16+
| Open browser | ${HOME_PAGE_URL} | options=${options} | |
17+
| `Run Async Keywords` | Click Element | id:login_button | AND |
18+
| ... | Wait for response url | ${HOME_PAGE_URL}/home.html | |
19+
20+
"""
1221
self.ctx.load_async_keywords()
1322
run_keyword = _RunKeyword()
14-
"""Executes all the given keywords in a asynchronous and wait until all keyword complete"""
1523
self.loop.run_until_complete( self._run_async_keywords(run_keyword._split_run_keywords(list(keywords))) )
1624

1725
async def _run_async_keywords(self, iterable):

PuppeteerLibrary/keywords/waiting.py

Lines changed: 128 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,54 +11,169 @@ def __init__(self, ctx):
1111

1212
@keyword
1313
def wait_for_request_url(self, url, method='GET', timeout=None):
14-
"""Wait for request url"""
14+
"""
15+
Wait until web application sent request to ``url``.
16+
17+
The ``url`` is request url.
18+
19+
The ``method`` is HTTP Request Methods:
20+
- GET (default)
21+
- POST
22+
- PUT
23+
- HEAD
24+
- DELETE
25+
- PATCH
26+
27+
Example:
28+
29+
| Open browser | ${HOME_PAGE_URL} | options=${options} | |
30+
| Input Text | id:username | foo | |
31+
| Input Text | id:password | bar | |
32+
| Run Async Keywords | Click Element | id:login_button | AND |
33+
| ... | `Wait For Request Url` | ${URL_API}/login | POST |
34+
35+
"""
1536
return self.loop.run_until_complete(self.async_func.wait_for_request_url_async(url, method , timeout))
1637

1738
@keyword
1839
def wait_for_response_url(self, url, status=200, timeout=None):
19-
"""Wait for response url"""
40+
"""
41+
Wait until web application received response from ``url``.
42+
43+
The ``url`` is response url.
44+
45+
The ``status`` is HTTP Status Codes:
46+
- 200 (default)
47+
- 201
48+
- 204
49+
- 400
50+
- 401
51+
- 404
52+
- 500
53+
Reference:[https://restfulapi.net/http-status-codes/|https://restfulapi.net/http-status-codes/]
54+
55+
Example:
56+
57+
| Open browser | ${HOME_PAGE_URL} | options=${options} | |
58+
| Input Text | id:username | foo | |
59+
| Input Text | id:password | bar | |
60+
| Run Async Keywords | Click Element | id:login_button | AND |
61+
| ... | `Wait For Response Url` | ${URL_API}/login | 200 |
62+
63+
"""
2064
return self.loop.run_until_complete(self.async_func.wait_for_response_url_async(url, status, timeout))
2165

2266
@keyword
2367
def wait_for_function(self, page_function):
24-
"""Wait for page trigger function"""
68+
"""
69+
Waits until web application executes java script function.
70+
71+
The ``page_function`` is java script function.
72+
73+
"""
2574
return self.loop.run_until_complete(self.async_func.wait_for_function_async(page_function))
2675

2776
@keyword
2877
def wait_for_navigation(self):
29-
"""Wait for navigation from any redirect"""
78+
"""
79+
Waits until web page navigates to new url or reloads.
80+
81+
Example:
82+
83+
| Open browser | ${HOME_PAGE_URL} | options=${options} | |
84+
| Input Text | id:username | foo | |
85+
| Input Text | id:password | bar | |
86+
| Run Async Keywords | Click Element | id:login_button | AND |
87+
| ... | `Wait For Navigation` | | |
88+
"""
3089
return self.loop.run_until_complete(self.async_func.wait_for_navigation_async())
3190

3291
@keyword
3392
def wait_until_page_contains_element(self, locator, timeout=None):
34-
"""Wait until page contains element within specific timeout"""
93+
"""
94+
Waits until ``locator`` element appears on current page.
95+
96+
Example:
97+
98+
| Open browser | ${HOME_PAGE_URL} | options=${options} |
99+
| `Wait Until Page Contains Element` | id:username | |
100+
"""
35101
return self.loop.run_until_complete(self.async_func.wait_for_selenium_selector(locator, timeout))
36102

37103
@keyword
38104
def wait_until_element_is_hidden(self, locator, timeout=None):
105+
"""
106+
Waits until ``locator`` element is hide or removed from web page.
107+
108+
Example:
109+
110+
| Run Async Keywords | Click Element | id:login_button | AND |
111+
| ... | Wait For Navigation | | |
112+
| `Wait Until Element Is Hidden` | id:login_button | | |
113+
"""
39114
return self.loop.run_until_complete(self.async_func.wait_until_element_is_hidden_async(locator, timeout))
40115

41116
@keyword
42117
def wait_until_element_is_visible(self, locator, timeout=None):
118+
"""
119+
Waits until ``locator`` element is displayed on web page.
120+
121+
Example:
122+
123+
| Run Async Keywords | Click Element | id:login_button | AND |
124+
| ... | Wait For Navigation | | |
125+
| `Wait Until Element Is Visible` | id:welcome | | |
126+
"""
43127
return self.loop.run_until_complete(self.async_func.wait_until_element_is_visible_async(locator, timeout))
44128

45129
@keyword
46130
def wait_until_page_contains(self, text, timeout=None):
47-
"""Waits until ``text`` appears on the current page"""
131+
"""
132+
Waits until ``text`` appears on current page.
133+
134+
Example:
135+
136+
| Run Async Keywords | Click Element | id:login_button | AND |
137+
| ... | Wait For Navigation | | |
138+
| `Wait Until Page Contains` | Invalid user name or password | | |
139+
"""
48140
return self.loop.run_until_complete(self.async_func.wait_until_page_contains_async(text, timeout))
49141

50142
@keyword
51143
def wait_until_page_does_not_contains(self, text, timeout=None):
52-
"""Waits until ``text`` appears on the current page"""
144+
"""
145+
Waits until ``text`` disappears on current page.
146+
147+
Example:
148+
149+
| Run Async Keywords | Click Element | id:login_button | AND |
150+
| ... | Wait For Navigation | | |
151+
| `Wait Until Page Does Not Contains` | Please input your user name | | |
152+
"""
53153
return self.loop.run_until_complete(self.async_func.wait_until_page_does_not_contains_async(text, timeout))
54154

55155
@keyword
56-
def wait_until_element_contains(self, selenium_locator, text, timeout=None):
57-
"""Waits until the ``element`` contains ``text``."""
58-
return self.loop.run_until_complete(self.async_func.wait_until_element_contains_async(selenium_locator, text, timeout))
156+
def wait_until_element_contains(self, locator, text, timeout=None):
157+
"""
158+
Waits until ``locator`` element contains ``text``.
159+
160+
Example:
161+
162+
| Open browser | ${HOME_PAGE_URL} | options=${options} |
163+
| `Wait Until Element Contains` | css:#container p | Please input your user name |
164+
"""
165+
return self.loop.run_until_complete(self.async_func.wait_until_element_contains_async(locator, text, timeout))
59166

60167
@keyword
61-
def wait_until_element_does_not_contains(self, selenium_locator, text, timeout=None):
62-
"""Waits until the ``element`` does not contains ``text``."""
63-
return self.loop.run_until_complete(self.async_func.wait_until_element_does_not_contains_async(selenium_locator, text, timeout))
168+
def wait_until_element_does_not_contains(self, locator, text, timeout=None):
169+
"""
170+
Waits until ``locator`` element does not contains ``text``.
171+
172+
Example:
173+
174+
| Run Async Keywords | Click Element | id:login_button | AND |
175+
| ... | Wait For Navigation | | |
176+
| `Wait Until Element Does Not Contains` | css:#container p | Please input your user name | |
177+
"""
178+
return self.loop.run_until_complete(self.async_func.wait_until_element_does_not_contains_async(locator, text, timeout))
64179

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
# robotframework-puppeteer
2-
Puppeteer with robotframework. This project connect between robotframework and puppeteer using [pyppeteer](https://github.com/pyppeteer/pyppeteer).
2+
Robot Framework Puppeteer Library powered by [Pyppeteer](https://github.com/pyppeteer/pyppeteer).
3+
Improve automated web testing with native functionality from [Puppeteer](https://github.com/puppeteer/puppeteer) by Google.
34

4-
We aim for provide keyword similar to robotframework-seleniumlibrary and add core puppeteer functionality that will improve test experiences
5+
We aim to provide keywords similar to robotframework-seleniumlibrary and add core puppeteer functionality that will improve test experiences.
6+
Example:
7+
- _Handle HTTP Request_
8+
- _Handle HTTP Response_
9+
- _Intercepter Http_
10+
- _Intercepter javascript function_
511

6-
Example: _Handle HTTP Request_, _Handle HTTP Response_ or _Intercepter http request & response_
712

813
Keyword documentation
914
---------------------

contributing.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ or slack with the owners of this repository before making a change.
66
Please note we have a code of conduct, please follow it in all your interactions with the project.
77

88
## Pull Request Process
9-
In progress
9+
In progress ...
1010

1111
## Code of Conduct
12-
In progress
12+
In progress ...
1313

1414
## Release steps
1515
Please follow the release steps for ensure that all release will be in the same standard and pattern.
1616

17+
In progress ...
18+
1719
### Step for regenerate keywords documents
1820
Command for Generate document
1921

0 commit comments

Comments
 (0)