Skip to content

Commit cafc0b4

Browse files
authored
Merge pull request #1865 from emanlove/add-expected-conditions-1827
Add expected conditions 1827
2 parents f4f5d5d + cc41bc1 commit cafc0b4

17 files changed

Lines changed: 335 additions & 32 deletions

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
matrix:
1212
python-version: [3.8, 3.11] # 3.12, pypy-3.9
1313
rf-version: [5.0.1, 6.1.1, 7.0]
14-
selenium-version: [4.14.0, 4.15.2, 4.16.0] #4.17.0, 4.18.0
14+
selenium-version: [4.14.0, 4.15.2, 4.16.0, 4.17.2, 4.18.1, 4.19.0]
1515
browser: [firefox, chrome, headlesschrome] #edge
1616

1717
steps:
@@ -88,7 +88,7 @@ jobs:
8888
# xvfb-run --auto-servernum python atest/run.py --zip headlesschrome --grid True
8989

9090
- uses: actions/upload-artifact@v1
91-
if: success() || failure()
91+
if: failure()
9292
with:
9393
name: SeleniumLibrary Test results
9494
path: atest/zip_results
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
*** Test Cases ***
2+
# Wait Until Element State Is (Not)
3+
# Get Element State
4+
# Element States Should (Not) Be
5+
6+
Check waiting for condition that takes a element
7+
Fail
8+
9+
Check waiting for condition that takes a title
10+
Fail
11+
12+
Check waiting for condition that takes a url
13+
Fail
14+
Wait Until url contains google
15+
# verify took 2 seconds
16+
17+
Check waiting for condition that takes locator and string
18+
Wait Until Element State Is ${condition} ${locator} ${string}
19+
Wait Until Element State Is ${condition} ${element}
20+
Wait Until Condition Is ${condition} ${target}
21+
Wait Until Condition Is ${condition} ${whatelse you need for this condition}
22+
23+
24+
Wait Until State Is number_of_windows_to_be
25+
Wait Until Expected Condition Is number_of_windows_to_be
26+
Wait Until Condition Is number of windows to be 5
27+
Wait Until Condition Is text to be present in element attribute //some/xpath/to/an/element href http://hello
28+
29+
Wait Until Condition Is number of windows to be 5 text to be present in element attribute //some/xpath/to/an/element href http://hello
30+
31+
Wait Until number of windows to be 5
32+
Wait Until text to be present in element attribute //some/xpath/to/an/element href http://hello
33+
Get Condition
34+
Is number of windows to be 5

atest/acceptance/keywords/choose_file.robot

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ Choose File With Grid From Library Using SL choose_file method
4545

4646
Input Text Should Work Same Way When Not Using Grid
4747
[Documentation]
48-
... LOG 1:6 DEBUG GLOB: POST*/session/*/clear {*
49-
... LOG 1:9 DEBUG Finished Request
50-
... LOG 1:10 DEBUG GLOB: POST*/session/*/value*"text": "*
51-
... LOG 1:13 DEBUG Finished Request
52-
... LOG 1:14 DEBUG NONE
48+
... LOG 1:6 DEBUG GLOB: POST*/session/*/clear {*
49+
... LOG 1:9 DEBUG Finished Request
50+
... LOG 1:10 DEBUG REGEXP: POST.*/session/.*/value.*['\\\"]text['\\\"]: ['\\\"].*
51+
... LOG 1:13 DEBUG Finished Request
52+
... LOG 1:14 DEBUG NONE
5353
[Tags] NoGrid
5454
[Setup] Touch ${CURDIR}${/}temp.txt
5555
Input Text file_to_upload ${CURDIR}${/}temp.txt

atest/acceptance/keywords/click_element.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Click Element Action Chain
4040
[Tags] NoGrid
4141
[Documentation]
4242
... LOB 1:1 INFO Clicking 'singleClickButton' using an action chain.
43-
... LOG 1:6 DEBUG GLOB: *actions {"actions": [{*
43+
... LOG 1:6 DEBUG REGEXP: .*actions {['\\\"]actions['\\\"]: \\\[\\\{.*
4444
Click Element singleClickButton action_chain=True
4545
Element Text Should Be output single clicked
4646

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
*** Settings ***
2+
Test Setup Go To Page "javascript/expected_conditions.html"
3+
Resource ../resource.robot
4+
5+
*** Test Cases ***
6+
Wait For Expected Conditions One Argument
7+
Title Should Be Original
8+
Click Element link=delayed change title
9+
Wait For Expected Condition title_is Delayed
10+
Title Should Be Delayed
11+
12+
Wait For Expected Condition Times out within set timeout
13+
[Documentation] FAIL REGEXP: TimeoutException: Message: Expected Condition not met within set timeout of 0.3*
14+
Title Should Be Original
15+
Click Element link=delayed change title
16+
Wait For Expected Condition title_is Delayed timeout=0.3
17+
18+
Wait For Expected Conditions using WebElement as locator
19+
Click Button Change the button state
20+
${dynamic_btn}= Get WebElement id:enabledDisabledBtn
21+
Wait For Expected Condition element_to_be_clickable ${dynamic_btn}
22+
23+
Wait For Expected Conditions Where Condition Written With Spaces
24+
Title Should Be Original
25+
Click Element link=delayed change title
26+
Wait For Expected Condition title is Delayed
27+
Title Should Be Delayed
28+
29+
Wait For Expected Conditions Where Condition Is Variable
30+
${condition}= Set Variable title is
31+
Title Should Be Original
32+
Click Element link=delayed change title
33+
Wait For Expected Condition ${condition} Delayed
34+
Title Should Be Delayed
35+
36+
Wait For Expected Conditions Where Condition Is Strange Case
37+
Click Button Change the button state
38+
${dynamic_btn}= Get WebElement id:enabledDisabledBtn
39+
Wait For Expected Condition EleMENT tO BE cLiCkAbLe ${dynamic_btn}
40+
41+
Wait For Non Existing Expected Conditions
42+
Click Button Change the button state
43+
${dynamic_btn}= Get WebElement id:enabledDisabledBtn
44+
Run Keyword And Expect Error this_is_not_an_expected_con_dition is an unknown expected condition
45+
... Wait For Expected Condition this_is not an expected con dition ${dynamic_btn}
46+
47+
Wait For Expected Conditions When Condition Includes Locator
48+
Title Should Be Original
49+
${byElem}= Evaluate ("id","added_btn")
50+
Click Element link:delayed add element
51+
Wait For Expected Condition Presence Of Element Located ${byElem}
52+
Click Element id:added_btn

atest/acceptance/keywords/page_load_timeout.robot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Test Teardown Close Browser And Reset Page Load Timeout
77
*** Test Cases ***
88
Should Open Browser With Default Page Load Timeout
99
[Documentation] Verify that 'Open Browser' changes the page load timeout.
10-
... LOG 1.1.1:27 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {"pageLoad": 300000}
10+
... LOG 1.1.1:27 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {['\\\"]pageLoad['\\\"]: 300000}
1111
... LOG 1.1.1:29 DEBUG STARTS: Remote response: status=200
1212
# Note: previous log check was 33 and 37. Recording to see if something is swtiching back and forth
1313
Open Browser To Start Page
@@ -21,8 +21,8 @@ Should Run Into Timeout Exception
2121

2222
Should Set Page Load Timeout For All Opened Browsers
2323
[Documentation] One browser is already opened as global suite setup.
24-
... LOG 2:1 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {"pageLoad": 5000}
25-
... LOG 2:5 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {"pageLoad": 5000}
24+
... LOG 2:1 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {['\\\"]pageLoad['\\\"]: 5000}
25+
... LOG 2:5 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {['\\\"]pageLoad['\\\"]: 5000}
2626
Open Browser To Start Page
2727
Set Selenium Page Load Timeout 5 s
2828

atest/acceptance/multiple_browsers_options.robot

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,32 @@ Documentation Creating test which would work on all browser is not possible.
99
*** Test Cases ***
1010
Chrome Browser With Selenium Options As String
1111
[Documentation]
12-
... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"*
13-
... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
12+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].*
13+
... LOG 1:14 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].*
1414
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
1515
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage")
1616

1717
Chrome Browser With Selenium Options As String With Attribute As True
1818
[Documentation]
19-
... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"*
20-
... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
21-
... LOG 1:14 DEBUG GLOB: *"--headless=new"*
19+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].*
20+
... LOG 1:14 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].*
21+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]--headless=new['\\\"].*
2222
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
2323
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_argument ( "--headless=new" )
2424

2525
Chrome Browser With Selenium Options With Complex Object
2626
[Tags] NoGrid
2727
[Documentation]
28-
... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"*
29-
... LOG 1:14 DEBUG GLOB: *"mobileEmulation": {"deviceName": "Galaxy S5"*
30-
... LOG 1:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
28+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].*
29+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]mobileEmulation['\\\"]: {['\\\"]deviceName['\\\"]: ['\\\"]Galaxy S5['\\\"].*
30+
... LOG 1:14 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].*
3131
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
3232
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_experimental_option( "mobileEmulation" , { 'deviceName' : 'Galaxy S5'})
3333

3434
Chrome Browser With Selenium Options Object
3535
[Documentation]
36-
... LOG 2:14 DEBUG GLOB: *"goog:chromeOptions"*
37-
... LOG 2:14 DEBUG GLOB: *args": ["--disable-dev-shm-usage"?*
36+
... LOG 2:14 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].*
37+
... LOG 2:14 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].*
3838
${options} = Get Chrome Options
3939
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
4040
... desired_capabilities=${DESIRED_CAPABILITIES} options=${options}
@@ -47,8 +47,8 @@ Chrome Browser With Selenium Options Invalid Method
4747

4848
Chrome Browser With Selenium Options Argument With Semicolon
4949
[Documentation]
50-
... LOG 1:14 DEBUG GLOB: *"goog:chromeOptions"*
51-
... LOG 1:14 DEBUG GLOB: *["has;semicolon"*
50+
... LOG 1:14 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].*
51+
... LOG 1:14 DEBUG REGEXP: .*\\\[['\\\"]has;semicolon['\\\"].*
5252
Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL}
5353
... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("has;semicolon")
5454

atest/resources/html/javascript/dynamic_content.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@
1010
container = document.getElementById(target_container);
1111
container.appendChild(p);
1212
}
13+
14+
function delayed_title_change() {
15+
setTimeout(function(){
16+
document.title='Delayed';
17+
},600);
18+
}
1319
</script>
1420
</head>
1521
<body>
1622
<a href="javascript:return false;" onclick="document.title='Changed'; return false;">change title</a><br/>
23+
<a href="javascript:return false;" onclick="delayed_title_change(); return false;">delayed change title</a><br/>
1724
<a href="javascript:return false;" onclick="add_content('target', 'added content'); return false;">add content</a><br/>
1825
<a id="unicode" href="javascript:return false;" onclick="document.title='äää'; return false;">title to ääää</a><br/>
1926
<p>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5+
<title>Original</title>
6+
<!-- Note the timeouts in the functions are chosen such they constitute
7+
a set with distinct subset sums. That is is a combination of any two
8+
or more were to be executed the total time for that distinct combination
9+
would be unique. This was done so we could do a ALL/AND/OR type of test
10+
and know that with the combination of expected conditions the execution
11+
was successful as the unique time took place. -->
12+
<!-- The set we are using is {6,9,11,12,13} -->
13+
<!-- (could also use {3,5,6,7} which would reduce total time)-->
14+
<script type="text/javascript">
15+
function add_content(target_container, content) {
16+
p = document.createElement('p');
17+
p.appendChild(document.createTextNode(content));
18+
container = document.getElementById(target_container);
19+
container.appendChild(p);
20+
}
21+
22+
function delayed_button_state() {
23+
setTimeout(function() {
24+
state_btn = document.getElementById('enabledDisabledBtn')
25+
if (state_btn.hasAttribute("disabled")) {
26+
state_btn.removeAttribute("disabled")
27+
state_btn.value = "Enabled"
28+
} else {
29+
state_btn.setAttribute("disabled", "")
30+
state_btn.value = "Disabled"
31+
}
32+
},900)
33+
}
34+
function delayed_title_change() {
35+
setTimeout(function(){
36+
document.title='Delayed';
37+
},600);
38+
}
39+
40+
function delayed_add_element() {
41+
setTimeout(function(){
42+
const newElem = document.createElement("input");
43+
newElem.setAttribute("type", "button");
44+
newElem.setAttribute("id", "added_btn");
45+
newElem.setAttribute("value", "Added Button");
46+
const container = document.getElementById("container");
47+
document.body.insertBefore(newElem, container);
48+
},1100);
49+
}
50+
</script>
51+
</head>
52+
<body>
53+
<a href="javascript:return false;" onclick="document.title='Changed'; return false;">change title</a><br/>
54+
<a href="javascript:return false;" onclick="delayed_title_change(); return false;">delayed change title</a><br/>
55+
<a href="javascript:return false;" onclick="delayed_add_element(); return fales;">delayed add element</a><br/>
56+
<a href="javascript:return false;" onclick="add_content('target', 'added content'); return false;">add content</a><br/>
57+
<a id="unicode" href="javascript:return false;" onclick="document.title='äää'; return false;">title to ääää</a><br/>
58+
<p>
59+
<input type="radio" name="group" value="title"
60+
onclick="document.title='Changed by Button';" />Change Title<br/>
61+
<input type="radio" name="group" value="content"
62+
onclick="add_content('button_target', 'added by button');"/>Add Content<br/>
63+
</p>
64+
<div id="target">
65+
</div>
66+
<div id="button_target">
67+
</div>
68+
<form name=myform>
69+
<input type=button value="Change the title"
70+
onClick="if(confirm('Really change the title?'))
71+
document.title += ' Changed!';" >
72+
</form>
73+
<p>
74+
<input type=button id=stateChangeBtn value="Change the button state"
75+
onClick="delayed_button_state()" />
76+
<input type=button id=enabledDisabledBtn value="Disabled"
77+
disabled />
78+
</p>
79+
<p>
80+
<div id="container"></div>
81+
</p>
82+
<p>
83+
<form name=titleChanger>
84+
<td>
85+
<input type=text id=titleChangeTxt value="Enter Title here">
86+
</td>
87+
<td>
88+
<input type=button id=titleChangeBtn value="Set Title"
89+
onClick="document.title = document.getElementById('titleChangeTxt').value;" >
90+
</td>
91+
</form>
92+
</p>
93+
</body>
94+
</html>
95+

atest/run.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252

5353
from robot import rebot_cli
5454
from robot import __version__ as robot_version
55+
from selenium import __version__ as selenium_version
5556
from robot.utils import is_truthy
5657

5758
try:
@@ -251,15 +252,15 @@ def process_output(browser):
251252
return exit.code
252253

253254

254-
def create_zip():
255+
def create_zip(browser = None):
255256
if os.path.exists(ZIP_DIR):
256257
shutil.rmtree(ZIP_DIR)
257258
os.mkdir(ZIP_DIR)
258259
python_version = platform.python_version()
259-
zip_name = f"rf-{robot_version}-python-{python_version}.zip"
260+
zip_name = f"rf-{robot_version}-python-{python_version}-selenium-{selenium_version}-{browser}.zip"
260261
zip_path = os.path.join(ZIP_DIR, zip_name)
261262
print("Zip created in: %s" % zip_path)
262-
zip_file = zipfile.ZipFile(zip_path, "w")
263+
zip_file = zipfile.ZipFile(zip_path, "a")
263264
for root, dirs, files in os.walk(RESULTS_DIR):
264265
for file in files:
265266
file_path = os.path.join(root, file)
@@ -326,5 +327,5 @@ def create_zip():
326327
interpreter, browser, rf_options, selenium_grid, event_firing_webdriver
327328
)
328329
if args.zip:
329-
create_zip()
330+
create_zip(browser)
330331
sys.exit(failures)

0 commit comments

Comments
 (0)