Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ Examples/traces/
Examples/state-admin.json
Examples/test-report/
test-report/
puppeteer-screenshot-.*.png
37 changes: 18 additions & 19 deletions Examples/form-handler/element-properties.robot
Original file line number Diff line number Diff line change
@@ -1,61 +1,60 @@
*** Settings ***
Library PuppeteerLibrary
Test Setup Open browser to test page
Test Teardown Close All Browser
Library PuppeteerLibrary
Test Setup Open browser to test page
Test Teardown Close All Browser
Suite Teardown Close Puppeteer

*** Variables ***
${DEFAULT_BROWSER} chrome
${HOME_PAGE_URL} http://127.0.0.1:7272/basic-html-elements.html


*** Test Cases ***
Count elements
${No of h2} = Get Element Count css=h2
Should Be Equal As Numbers 14 ${No of h2}

Count non existing element
Set Timeout 1s
${No of h2} = Get Element Count css=Hnotexisting
Should Be Equal As Numbers 0 ${No of h2}

Get element attribute
${type value} = Get Element Attribute id=alert_confirm type
${type value} = Get Element Attribute id=alert_confirm type
Should Be Equal As Strings button ${type value}

Element proprty is enable
Element Should Be Enabled id:prop-enable

Element property is disable
Element Should Be Disabled id:prop-disable
Run Keyword And Expect Error REGEXP:Element 'id:prop-enable' is enabled Element Should Be Disabled id:prop-enable
Run Keyword And Expect Error REGEXP:.*'id:prop-enable' is enabled.* Element Should Be Disabled id:prop-enable

Element is visible and not visible
[Tags] Ignore_firefox
#TODO Need to recheck why firefox unstable
Element Should Be Visible id:prop-visible
Element Should Not Be Visible id:prop-hide
Run Keyword And Expect Error REGEXP:Element 'id:prop-hide' is not be visible Element Should Be Visible id:prop-hide
Run Keyword And Expect Error REGEXP:.*is not be visible.* Element Should Be Visible id:prop-hide

Get Element Text
${text} = Get Text id=prop-text
${text} = Get Text id=prop-text
Should Contain ${text} Please

Element should containt text
Element Should Contain id=prop-text Please ${True}

Element should not contain text
Element Should Not Contain id=prop-text Please input2 ${True}

Element text should be
Element Text Should Be id=prop-text Please input ${True}
Element Text Should Be id=prop-text Please input ${True}

Element text should not be
Element Text Should Not Be id=prop-text Please ${True}
Element Text Should Not Be id=prop-text Please ${True}

*** Keywords ***
Open browser to test page
${BROWSER} = Get variable value ${BROWSER} ${DEFAULT_BROWSER}
${HEADLESS} Get variable value ${HEADLESS} ${False}
&{options} = create dictionary headless=${HEADLESS}
Open browser ${HOME_PAGE_URL} browser=${BROWSER} options=${options}
${BROWSER} = Get variable value ${BROWSER} ${DEFAULT_BROWSER}
${HEADLESS} Get variable value ${HEADLESS} ${False}
&{options} = create dictionary headless=${HEADLESS}
Open browser ${HOME_PAGE_URL} browser=${BROWSER} options=${options}
18 changes: 8 additions & 10 deletions Examples/utilities/log-messages.robot
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
*** Settings ***
Library PuppeteerLibrary
Test Setup Open browser to test page
Test Teardown Close All Browser
Library PuppeteerLibrary
Test Setup Open browser to test page
Test Teardown Close All Browser
Suite Teardown Close Puppeteer


*** Variables ***
${DEFAULT_BROWSER} chrome
${HOME_PAGE_URL} http://127.0.0.1:7272/basic-html-elements.html


*** Test Cases ***
No node found when click
Run Keyword And Expect Error REGEXP:.* Click Element id:login_button_error
Set Timeout 2s
Run Keyword And Expect Error * Click Element id:login_button_error

Test log error for sync keywords
Run Keyword And Ignore Error Click Element id:login_button_error

Test log error for async keywords
Run Keyword And Ignore Error Run Async Keywords
Run Keyword And Ignore Error Run Async Keywords
... Click Element id:login_button_error AND
... Click Element id:login_button_2


*** Keywords ***
Open browser to test page
${BROWSER} = Get variable value ${BROWSER} ${DEFAULT_BROWSER}
${BROWSER} = Get variable value ${BROWSER} ${DEFAULT_BROWSER}
${HEADLESS} = Get variable value ${HEADLESS} ${True}
&{options} = create dictionary headless=${HEADLESS}
&{options} = create dictionary headless=${HEADLESS}
Open browser ${HOME_PAGE_URL} browser=${BROWSER} options=${options}
20 changes: 12 additions & 8 deletions PuppeteerLibrary/keywords/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def click_element(self, locator, noWaitAfter='False'):
"""
self.info(f"Clicking element '{locator}'.")
self.loop.run_until_complete(self.get_async_keyword_group().click_element(
locator=locator,
locator=locator,
noWaitAfter=noWaitAfter
))

Expand All @@ -52,7 +52,8 @@ def click_button(self, locator):
| `Click Button` | id:submit |
"""
self.info(f"Clicking button '{locator}'.")
self.loop.run_until_complete(self.get_async_keyword_group().click_button(locator))
self.loop.run_until_complete(
self.get_async_keyword_group().click_button(locator))

@keyword
def click_image(self, locator):
Expand All @@ -63,22 +64,25 @@ def click_image(self, locator):
| `Click Image` | id:cat_image |
"""
self.info(f"Clicking image '{locator}'.")
self.loop.run_until_complete(self.get_async_keyword_group().click_image(locator))
self.loop.run_until_complete(
self.get_async_keyword_group().click_image(locator))

@keyword
def click_element_at_coordinate(self, locator, xoffset, yoffset):
""" Click element at specifict coordiate x and y offset
"""
self.info(f"Clicking element at coordinate '{locator}' at xoffset: '{xoffset}', yoffset: '{yoffset}'.")
self.loop.run_until_complete(self.get_async_keyword_group().click_element_at_coordinate(locator, xoffset, yoffset))
self.info(
f"Clicking element at coordinate '{locator}' at xoffset: '{xoffset}', yoffset: '{yoffset}'.")
self.loop.run_until_complete(self.get_async_keyword_group(
).click_element_at_coordinate(locator, xoffset, yoffset))

@keyword
def upload_file(self, locator, file_path):
""" Upload file
"""
return self.loop.run_until_complete(self.get_async_keyword_group().upload_file(locator, file_path))

@keyword
@keyword
def press_keys(self, locator, *keys):
""" Press Keys

Expand Down Expand Up @@ -129,10 +133,10 @@ def element_should_not_be_visible(self, locator):
"""
return self.loop.run_until_complete(self.get_async_keyword_group().element_should_not_be_visible(locator))


##############################
# Property
##############################

@keyword
def get_text(self, locator):
"""Returns text value of element identified by ``locator``.
Expand Down Expand Up @@ -191,7 +195,7 @@ def element_text_should_not_be(self, locator, expected, ignore_case=False):
# Query Element
##############################
@keyword
def get_element_count(self, locator):
def get_element_count(self, locator, timeout=None):
""" Returns the number of elements matching ``locator``.
"""
try:
Expand Down
30 changes: 19 additions & 11 deletions PuppeteerLibrary/keywords/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,33 @@ def set_timeout(self, timeout):
See the Timeout section above for more information.

Example:

| Open page that loads slowly | | |
| Set Timeout | ${orig timeout} | |

"""
orig_timeout = self.ctx.timeout
self.ctx.get_current_library_context().set_default_timeout(timestr_to_secs(timeout))
if self.ctx.get_current_library_context().browser_type.lower() == 'ptchrome':
self.ctx.get_current_library_context().set_default_timeout(timestr_to_secs(timeout))
else:
self.loop.run_until_complete(
self.ctx.get_current_library_context().set_default_timeout(timestr_to_secs(timeout))
)
self.info('Original timeout is ' + str(orig_timeout) + ' seconds')
return orig_timeout

@keyword
def run_async_keywords_and_return_first_completed(self, *keywords):
"""Executes all the given keywords in a asynchronous and wait until first keyword is completed

``Return`` Array of result for each keywords based on index

Example
| `Run Async Keywords And Return First Completed` | Wait for response url | ${HOME_PAGE_URL}/login.html | AND |
| ... | Wait for response url | ${HOME_PAGE_URL}/home.html | |
"""
run_keyword = _RunKeyword()
return self.loop.run_until_complete( self._run_async_keywords_first_completed(run_keyword._split_run_keywords(list(keywords))) )
return self.loop.run_until_complete(self._run_async_keywords_first_completed(run_keyword._split_run_keywords(list(keywords))))

@keyword
def run_async_keywords(self, *keywords):
Expand All @@ -56,7 +61,7 @@ def run_async_keywords(self, *keywords):

"""
run_keyword = _RunKeyword()
return self.loop.run_until_complete( self._run_async_keywords(run_keyword._split_run_keywords(list(keywords))) )
return self.loop.run_until_complete(self._run_async_keywords(run_keyword._split_run_keywords(list(keywords))))

@keyword
def enable_debug_mode(self, slowMo=150, devtools=True):
Expand Down Expand Up @@ -89,11 +94,12 @@ async def disable_debug_mode_async():
self.ctx.debug_mode = False
self.ctx.clear_browser()

async def _run_async_keywords(self, iterable):
async def _run_async_keywords(self, iterable):
statements = []
for kw, args in iterable:
kw_name = kw.lower().replace(' ', '_')
async_keywords = self.ctx.keywords[kw_name].__self__.get_async_keyword_group()
async_keywords = self.ctx.keywords[kw_name].__self__.get_async_keyword_group(
)
statements.append(getattr(async_keywords, kw_name)(*args))
try:
return await asyncio.gather(*statements)
Expand All @@ -105,8 +111,10 @@ async def _run_async_keywords_first_completed(self, iterable):
index = 0
for kw, args in iterable:
kw_name = kw.lower().replace(' ', '_')
async_keywords = self.ctx.keywords[kw_name].__self__.get_async_keyword_group()
org_statements.append(self._wrapped_async_keyword_return_index(index, getattr(async_keywords, kw_name)(*args) ))
async_keywords = self.ctx.keywords[kw_name].__self__.get_async_keyword_group(
)
org_statements.append(self._wrapped_async_keyword_return_index(
index, getattr(async_keywords, kw_name)(*args)))
index += 1
statements = org_statements
error_stack_trace = ''
Expand All @@ -128,9 +136,9 @@ async def _run_async_keywords_first_completed(self, iterable):
error_stack_trace += str(e)+'\n'
continue
if len(pending) == 0:
raise Exception("All async keywords failed \r\n"+ error_stack_trace)
raise Exception(
"All async keywords failed \r\n" + error_stack_trace)

async def _wrapped_async_keyword_return_index(self, index, future):
await future
return index

2 changes: 1 addition & 1 deletion PuppeteerLibrary/playwright/playwright_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def is_server_started(self) -> bool:
return True
return False

def set_default_timeout(self, timeout):
async def set_default_timeout(self, timeout):
self.timeout = timeout
self.get_current_page().get_page().set_default_timeout(timeout * 1000)

Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
versioneer>=0.18
robotframework>=3.2.1
playwright==1.17.2
pyppeteer==0.2.6
# git+https://github.com/qahive/pyppeteer.git@dev2
playwright==1.21.0
pyppeteer==1.0.2
robotframework-libdoc2json>=0.4
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import versioneer
import re
from os.path import abspath, dirname, join
from setuptools import setup, find_packages
Expand All @@ -9,7 +10,6 @@

# Get the version from the _version.py versioneer file. For a git checkout,
# this is computed based on the number of commits since the last tag.
import versioneer
VERSION = str(versioneer.get_versions()['version']).split('+')[0]
del versioneer.get_versions

Expand Down Expand Up @@ -39,8 +39,8 @@
platforms='any',
install_requires=[
'robotframework>=3.2.1',
'playwright==1.17.2',
'pyppeteer==0.2.6',
'playwright==1.21.0',
'pyppeteer==1.0.2',
],
python_requires='>3.6',
# test_suite='nose.collector',
Expand Down