seleniumbase 4.16.2__py3-none-any.whl → 4.16.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sbase/steps.py +65 -0
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_helper.py +29 -1
- seleniumbase/common/exceptions.py +6 -1
- seleniumbase/console_scripts/sb_install.py +18 -4
- seleniumbase/core/browser_launcher.py +63 -8
- seleniumbase/core/recorder_helper.py +29 -1
- seleniumbase/fixtures/base_case.py +238 -10
- seleniumbase/fixtures/page_actions.py +131 -4
- seleniumbase/fixtures/shared_utils.py +5 -0
- seleniumbase/fixtures/words.py +15 -1
- seleniumbase/translate/chinese.py +4 -0
- seleniumbase/translate/dutch.py +4 -0
- seleniumbase/translate/french.py +4 -0
- seleniumbase/translate/italian.py +4 -0
- seleniumbase/translate/japanese.py +4 -0
- seleniumbase/translate/korean.py +4 -0
- seleniumbase/translate/master_dict.py +25 -0
- seleniumbase/translate/portuguese.py +4 -0
- seleniumbase/translate/russian.py +4 -0
- seleniumbase/translate/spanish.py +4 -0
- seleniumbase/undetected/patcher.py +5 -0
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/METADATA +45 -45
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/RECORD +28 -28
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/WHEEL +1 -1
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/LICENSE +0 -0
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.16.2.dist-info → seleniumbase-4.16.3.dist-info}/top_level.txt +0 -0
sbase/steps.py
CHANGED
@@ -168,6 +168,19 @@ def assert_exact_text(context, text, selector):
|
|
168
168
|
sb.assert_exact_text(text, selector)
|
169
169
|
|
170
170
|
|
171
|
+
@step("Assert non-empty text in '{selector}'")
|
172
|
+
@step('Assert non-empty text in "{selector}"')
|
173
|
+
@step("Assert text in '{selector}' is not empty")
|
174
|
+
@step('Assert text in "{selector}" is not empty')
|
175
|
+
@step("Text in '{selector}' should be non-empty")
|
176
|
+
@step('Text in "{selector}" should be non-empty')
|
177
|
+
@step("Text in '{selector}' should not be empty")
|
178
|
+
@step('Text in "{selector}" should not be empty')
|
179
|
+
def assert_non_empty_text(context, selector):
|
180
|
+
sb = context.sb
|
181
|
+
sb.assert_non_empty_text(selector)
|
182
|
+
|
183
|
+
|
171
184
|
@step("Highlight '{selector}'")
|
172
185
|
@step('Highlight "{selector}"')
|
173
186
|
@step("Highlight element '{selector}'")
|
@@ -492,6 +505,49 @@ def wait_for_text_in_element(context, text, selector):
|
|
492
505
|
sb.wait_for_text(text, selector)
|
493
506
|
|
494
507
|
|
508
|
+
@step("Wait for exact text '{text}' in '{selector}'")
|
509
|
+
@step('Wait for exact text "{text}" in "{selector}"')
|
510
|
+
@step("Wait for exact text '{text}' in \"{selector}\"")
|
511
|
+
@step('Wait for exact text "{text}" in \'{selector}\'')
|
512
|
+
@step("Wait for '{selector}' to have exact text '{text}'")
|
513
|
+
@step('Wait for "{selector}" to have exact text "{text}"')
|
514
|
+
@step('Wait for "{selector}" to have exact text \'{text}\'')
|
515
|
+
@step("Wait for '{selector}' to have exact text \"{text}\"")
|
516
|
+
@step("User waits for exact text '{text}' in '{selector}'")
|
517
|
+
@step('User waits for exact text "{text}" in "{selector}"')
|
518
|
+
@step("User waits for exact text '{text}' in \"{selector}\"")
|
519
|
+
@step('User waits for exact text "{text}" in \'{selector}\'')
|
520
|
+
@step("User waits for '{selector}' to have exact text '{text}'")
|
521
|
+
@step('User waits for "{selector}" to have exact text "{text}"')
|
522
|
+
@step('User waits for "{selector}" to have exact text \'{text}\'')
|
523
|
+
@step("User waits for '{selector}' to have exact text \"{text}\"")
|
524
|
+
def wait_for_exact_text_in_element(context, text, selector):
|
525
|
+
sb = context.sb
|
526
|
+
text = normalize_text(text)
|
527
|
+
sb.wait_for_exact_text(text, selector)
|
528
|
+
|
529
|
+
|
530
|
+
@step("Wait for non-empty text in '{selector}'")
|
531
|
+
@step('Wait for non-empty text in "{selector}"')
|
532
|
+
@step("Wait for '{selector}' to have non-empty text")
|
533
|
+
@step('Wait for "{selector}" to have non-empty text')
|
534
|
+
@step("User waits for non-empty text in '{selector}'")
|
535
|
+
@step('User waits for non-empty text in "{selector}"')
|
536
|
+
@step("User waits for '{selector}' to have non-empty text")
|
537
|
+
@step('User waits for "{selector}" to have non-empty text')
|
538
|
+
@step("Wait for '{selector}' to not have text")
|
539
|
+
@step('Wait for "{selector}" to not have text')
|
540
|
+
@step("Wait for text in '{selector}' to not be empty")
|
541
|
+
@step('Wait for text in "{selector}" to not be empty')
|
542
|
+
@step("User waits for '{selector}' to not have text")
|
543
|
+
@step('User waits for "{selector}" to not have text')
|
544
|
+
@step("User waits for text in '{selector}' to not be empty")
|
545
|
+
@step('User waits for text in "{selector}" to not be empty')
|
546
|
+
def wait_for_non_empty_text_in_element(context, selector):
|
547
|
+
sb = context.sb
|
548
|
+
sb.wait_for_non_empty_text(selector)
|
549
|
+
|
550
|
+
|
495
551
|
@step("Wait for text '{text}'")
|
496
552
|
@step('Wait for text "{text}"')
|
497
553
|
@step("User waits for text '{text}'")
|
@@ -839,12 +895,21 @@ def deferred_assert_text(context, text):
|
|
839
895
|
|
840
896
|
@step("Deferred assert exact text '{text}' in '{selector}'")
|
841
897
|
@step('Deferred assert exact text "{text}" in "{selector}"')
|
898
|
+
@step("Deferred assert exact text '{text}' in \"{selector}\"")
|
899
|
+
@step('Deferred assert exact text "{text}" in \'{selector}\'')
|
842
900
|
def deferred_assert_exact_text(context, text, selector):
|
843
901
|
sb = context.sb
|
844
902
|
text = normalize_text(text)
|
845
903
|
sb.deferred_assert_exact_text(text, selector)
|
846
904
|
|
847
905
|
|
906
|
+
@step("Deferred assert non-empty text in '{selector}'")
|
907
|
+
@step('Deferred assert non-empty text in "{selector}"')
|
908
|
+
def deferred_assert_non_empty_text(context, selector):
|
909
|
+
sb = context.sb
|
910
|
+
sb.deferred_assert_non_empty_text(selector)
|
911
|
+
|
912
|
+
|
848
913
|
@step("Process deferred asserts")
|
849
914
|
def process_deferred_asserts(context):
|
850
915
|
sb = context.sb
|
seleniumbase/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.16.
|
2
|
+
__version__ = "4.16.3"
|
@@ -435,18 +435,46 @@ def generate_gherkin(srt_actions):
|
|
435
435
|
sb_actions.append('%s "%s"' % (method, action[1][0]))
|
436
436
|
else:
|
437
437
|
sb_actions.append("%s '%s'" % (method, action[1][0]))
|
438
|
+
elif action[0] == "asnet":
|
439
|
+
method = "Assert non-empty text in"
|
440
|
+
if '"' not in action[1]:
|
441
|
+
sb_actions.append('%s "%s"' % (method, action[1]))
|
442
|
+
elif "'" not in action[1]:
|
443
|
+
sb_actions.append("%s '%s'" % (method, action[1]))
|
444
|
+
else:
|
445
|
+
sb_actions.append(
|
446
|
+
"%s '%s'" % (method, action[1].replace("'", "\\'"))
|
447
|
+
)
|
438
448
|
elif action[0] == "da_el":
|
439
449
|
method = "Deferred assert element"
|
440
450
|
if '"' not in action[1]:
|
441
451
|
sb_actions.append('%s "%s"' % (method, action[1]))
|
442
|
-
|
452
|
+
elif "'" not in action[1]:
|
443
453
|
sb_actions.append("%s '%s'" % (method, action[1]))
|
454
|
+
else:
|
455
|
+
sb_actions.append(
|
456
|
+
"%s '%s'" % (method, action[1].replace("'", "\\'"))
|
457
|
+
)
|
444
458
|
elif action[0] == "da_ep":
|
445
459
|
method = "Deferred assert element present"
|
446
460
|
if '"' not in action[1]:
|
447
461
|
sb_actions.append('%s "%s"' % (method, action[1]))
|
462
|
+
elif "'" not in action[1]:
|
463
|
+
sb_actions.append("%s '%s'" % (method, action[1]))
|
448
464
|
else:
|
465
|
+
sb_actions.append(
|
466
|
+
"%s '%s'" % (method, action[1].replace("'", "\\'"))
|
467
|
+
)
|
468
|
+
elif action[0] == "danet":
|
469
|
+
method = "Deferred assert non-empty text in"
|
470
|
+
if '"' not in action[1]:
|
471
|
+
sb_actions.append('%s "%s"' % (method, action[1]))
|
472
|
+
elif "'" not in action[1]:
|
449
473
|
sb_actions.append("%s '%s'" % (method, action[1]))
|
474
|
+
else:
|
475
|
+
sb_actions.append(
|
476
|
+
"%s '%s'" % (method, action[1].replace("'", "\\'"))
|
477
|
+
)
|
450
478
|
elif action[0] == "s_scr":
|
451
479
|
method = "Save screenshot as"
|
452
480
|
if '"' not in action[1]:
|
@@ -1,4 +1,5 @@
|
|
1
1
|
""" SeleniumBase Exceptions
|
2
|
+
LinkTextNotFoundException => Called when expected link text is not visible.
|
2
3
|
NoSuchFileException => Called when self.assert_downloaded_file(...) fails.
|
3
4
|
NoSuchOptionException => Called when select_option_by_*() lacks the option.
|
4
5
|
NotConnectedException => Called when Internet is not reachable when needed.
|
@@ -6,13 +7,17 @@
|
|
6
7
|
NotUsingChromiumException => Used by Chromium-only methods if not Chromium.
|
7
8
|
OutOfScopeException => Used by BaseCase methods when setUp() is skipped.
|
8
9
|
ProxyConnectionException => Called when the proxy connection failed.
|
9
|
-
TextNotVisibleException => Called when expected text
|
10
|
+
TextNotVisibleException => Called when the expected text is not visible.
|
10
11
|
TimeLimitExceededException => Called when exceeding "--time-limit=SECONDS".
|
11
12
|
TimeoutException => Called when some timeout limit has been exceeded.
|
12
13
|
VisualException => Called when there's a Visual Diff Assertion Failure.
|
13
14
|
"""
|
14
15
|
|
15
16
|
|
17
|
+
class LinkTextNotFoundException(Exception):
|
18
|
+
pass
|
19
|
+
|
20
|
+
|
16
21
|
class NoSuchFileException(Exception):
|
17
22
|
pass
|
18
23
|
|
@@ -150,15 +150,23 @@ def requests_get_with_retry(url):
|
|
150
150
|
try:
|
151
151
|
response = requests.get(url, proxies=proxies)
|
152
152
|
except Exception:
|
153
|
-
time.sleep(
|
154
|
-
|
153
|
+
time.sleep(1.1)
|
154
|
+
try:
|
155
|
+
response = requests.get(url, proxies=proxies)
|
156
|
+
except Exception:
|
157
|
+
time.sleep(1.2)
|
158
|
+
response = requests.get(url, proxies=proxies)
|
155
159
|
return response
|
156
160
|
else:
|
157
161
|
try:
|
158
162
|
response = requests.get(url)
|
159
163
|
except Exception:
|
160
|
-
time.sleep(
|
161
|
-
|
164
|
+
time.sleep(1.1)
|
165
|
+
try:
|
166
|
+
response = requests.get(url)
|
167
|
+
except Exception:
|
168
|
+
time.sleep(1.2)
|
169
|
+
response = requests.get(url)
|
162
170
|
return response
|
163
171
|
|
164
172
|
|
@@ -500,6 +508,12 @@ def main(override=None, intel_for_uc=None):
|
|
500
508
|
url_request = requests_get_with_retry(use_version)
|
501
509
|
if url_request.ok:
|
502
510
|
use_version = url_request.text.split("\r")[0].split("\n")[0]
|
511
|
+
if (
|
512
|
+
int(use_version.split(".")[0]) == 115
|
513
|
+
and use_version.startswith("115.0")
|
514
|
+
and use_version != "115.0.1901.183"
|
515
|
+
):
|
516
|
+
use_version = "115.0.1901.183"
|
503
517
|
download_url = "https://msedgedriver.azureedge.net/%s/%s" % (
|
504
518
|
use_version,
|
505
519
|
file_name,
|
@@ -153,7 +153,7 @@ def get_uc_driver_version():
|
|
153
153
|
return uc_driver_version
|
154
154
|
|
155
155
|
|
156
|
-
def
|
156
|
+
def find_chromedriver_version_to_use(use_version):
|
157
157
|
# Because https://chromedriver.chromium.org/downloads stops at 114
|
158
158
|
final_chromedriver = "114"
|
159
159
|
if (
|
@@ -177,11 +177,46 @@ def has_cf(text):
|
|
177
177
|
return False
|
178
178
|
|
179
179
|
|
180
|
-
def
|
180
|
+
def uc_special_open_if_cf(driver, url):
|
181
181
|
if (
|
182
182
|
(url.startswith("http:") or url.startswith("https:"))
|
183
183
|
and has_cf(requests_get(url).text)
|
184
184
|
):
|
185
|
+
with driver:
|
186
|
+
time.sleep(0.25)
|
187
|
+
driver.execute_script('window.open("%s","_blank");' % url)
|
188
|
+
driver.close()
|
189
|
+
driver.switch_to.window(driver.window_handles[-1])
|
190
|
+
else:
|
191
|
+
driver.open(url) # The original one
|
192
|
+
return None
|
193
|
+
|
194
|
+
|
195
|
+
def uc_open(driver, url):
|
196
|
+
if (url.startswith("http:") or url.startswith("https:")):
|
197
|
+
with driver:
|
198
|
+
time.sleep(0.25)
|
199
|
+
driver.open(url)
|
200
|
+
else:
|
201
|
+
driver.open(url) # The original one
|
202
|
+
return None
|
203
|
+
|
204
|
+
|
205
|
+
def uc_open_with_tab(driver, url):
|
206
|
+
if (url.startswith("http:") or url.startswith("https:")):
|
207
|
+
with driver:
|
208
|
+
time.sleep(0.25)
|
209
|
+
driver.execute_script('window.open("%s","_blank");' % url)
|
210
|
+
driver.close()
|
211
|
+
driver.switch_to.window(driver.window_handles[-1])
|
212
|
+
else:
|
213
|
+
driver.open(url) # The original one
|
214
|
+
return None
|
215
|
+
|
216
|
+
|
217
|
+
def uc_open_with_reconnect(driver, url):
|
218
|
+
"""Open a url, then reconnect with UC before switching to the window."""
|
219
|
+
if (url.startswith("http:") or url.startswith("https:")):
|
185
220
|
driver.execute_script('window.open("%s","_blank");' % url)
|
186
221
|
driver.reconnect(2.65)
|
187
222
|
driver.close()
|
@@ -804,6 +839,10 @@ def _set_chrome_options(
|
|
804
839
|
chrome_options.add_argument("--disable-prompt-on-repost")
|
805
840
|
chrome_options.add_argument("--dns-prefetch-disable")
|
806
841
|
chrome_options.add_argument("--disable-translate")
|
842
|
+
chrome_options.add_argument(
|
843
|
+
'--disable-features=OptimizationHints,OptimizationHintsFetching,'
|
844
|
+
'OptimizationGuideModelDownloading,OptimizationTargetPrediction'
|
845
|
+
)
|
807
846
|
if binary_location:
|
808
847
|
chrome_options.binary_location = binary_location
|
809
848
|
if not enable_3d_apis and not is_using_uc(undetectable, browser_name):
|
@@ -2177,6 +2216,7 @@ def get_local_driver(
|
|
2177
2216
|
if major_edge_version:
|
2178
2217
|
use_version = major_edge_version
|
2179
2218
|
driver_version = None
|
2219
|
+
edgedriver_upgrade_needed = False
|
2180
2220
|
if os.path.exists(LOCAL_EDGEDRIVER):
|
2181
2221
|
try:
|
2182
2222
|
output = subprocess.check_output(
|
@@ -2191,6 +2231,11 @@ def get_local_driver(
|
|
2191
2231
|
output = output.split(" ")[1].split(".")[0]
|
2192
2232
|
elif output.split(" ")[0] == "Microsoft":
|
2193
2233
|
# Microsoft Edge WebDriver VERSION
|
2234
|
+
if (
|
2235
|
+
"WebDriver 115.0" in output
|
2236
|
+
and "115.0.1901.183" not in output
|
2237
|
+
):
|
2238
|
+
edgedriver_upgrade_needed = True
|
2194
2239
|
output = output.split(" ")[3].split(".")[0]
|
2195
2240
|
else:
|
2196
2241
|
output = 0
|
@@ -2198,7 +2243,6 @@ def get_local_driver(
|
|
2198
2243
|
driver_version = output
|
2199
2244
|
except Exception:
|
2200
2245
|
pass
|
2201
|
-
edgedriver_upgrade_needed = False
|
2202
2246
|
local_edgedriver_exists = False
|
2203
2247
|
if LOCAL_EDGEDRIVER and os.path.exists(LOCAL_EDGEDRIVER):
|
2204
2248
|
local_edgedriver_exists = True
|
@@ -2477,7 +2521,9 @@ def get_local_driver(
|
|
2477
2521
|
if selenium4_or_newer:
|
2478
2522
|
try:
|
2479
2523
|
service = EdgeService(
|
2480
|
-
executable_path=LOCAL_EDGEDRIVER,
|
2524
|
+
executable_path=LOCAL_EDGEDRIVER,
|
2525
|
+
log_path=os.devnull,
|
2526
|
+
service_args=["--disable-build-check"],
|
2481
2527
|
)
|
2482
2528
|
driver = Edge(service=service, options=edge_options)
|
2483
2529
|
except Exception as e:
|
@@ -2503,6 +2549,7 @@ def get_local_driver(
|
|
2503
2549
|
service = EdgeService(
|
2504
2550
|
executable_path=LOCAL_EDGEDRIVER,
|
2505
2551
|
log_path=os.devnull,
|
2552
|
+
service_args=["--disable-build-check"],
|
2506
2553
|
)
|
2507
2554
|
# https://stackoverflow.com/a/56638103/7058266
|
2508
2555
|
sys_argv = sys.argv
|
@@ -2576,6 +2623,7 @@ def get_local_driver(
|
|
2576
2623
|
service = EdgeService(
|
2577
2624
|
executable_path=LOCAL_EDGEDRIVER,
|
2578
2625
|
log_path=os.devnull,
|
2626
|
+
service_args=["--disable-build-check"],
|
2579
2627
|
)
|
2580
2628
|
# https://stackoverflow.com/a/56638103/7058266
|
2581
2629
|
sys_argv = sys.argv
|
@@ -2852,7 +2900,7 @@ def get_local_driver(
|
|
2852
2900
|
from seleniumbase import config as sb_config
|
2853
2901
|
|
2854
2902
|
sb_config.multi_proxy = True
|
2855
|
-
use_version =
|
2903
|
+
use_version = find_chromedriver_version_to_use(use_version)
|
2856
2904
|
if (
|
2857
2905
|
LOCAL_CHROMEDRIVER
|
2858
2906
|
and os.path.exists(LOCAL_CHROMEDRIVER)
|
@@ -3007,7 +3055,7 @@ def get_local_driver(
|
|
3007
3055
|
)
|
3008
3056
|
with uc_lock: # Avoid multithreaded issues
|
3009
3057
|
uc_driver_version = get_uc_driver_version()
|
3010
|
-
use_version =
|
3058
|
+
use_version = find_chromedriver_version_to_use(use_version)
|
3011
3059
|
if (
|
3012
3060
|
(
|
3013
3061
|
uc_driver_version != use_version
|
@@ -3182,7 +3230,7 @@ def get_local_driver(
|
|
3182
3230
|
and int(major_chrome_version) >= 86
|
3183
3231
|
):
|
3184
3232
|
mcv = major_chrome_version
|
3185
|
-
mcv =
|
3233
|
+
mcv = find_chromedriver_version_to_use(mcv)
|
3186
3234
|
headless = True
|
3187
3235
|
headless_options = _set_chrome_options(
|
3188
3236
|
browser_name,
|
@@ -3281,7 +3329,14 @@ def get_local_driver(
|
|
3281
3329
|
)
|
3282
3330
|
driver.open = driver.get # Save copy of original
|
3283
3331
|
if uc_activated:
|
3284
|
-
driver.get = lambda url:
|
3332
|
+
driver.get = lambda url: uc_special_open_if_cf(driver, url)
|
3333
|
+
driver.uc_open = lambda url: uc_open(driver, url)
|
3334
|
+
driver.uc_open_with_tab = (
|
3335
|
+
lambda url: uc_open_with_tab(driver, url)
|
3336
|
+
)
|
3337
|
+
driver.uc_open_with_reconnect = (
|
3338
|
+
lambda url: uc_open_with_reconnect(driver, url)
|
3339
|
+
)
|
3285
3340
|
return driver
|
3286
3341
|
else: # Running headless on Linux (and not using --uc)
|
3287
3342
|
try:
|
@@ -463,18 +463,46 @@ def generate_sbase_code(srt_actions):
|
|
463
463
|
sb_actions.append(
|
464
464
|
"self.%s('%s')" % (method, action[1][0])
|
465
465
|
)
|
466
|
+
elif action[0] == "asnet":
|
467
|
+
method = "assert_non_empty_text"
|
468
|
+
if '"' not in action[1]:
|
469
|
+
sb_actions.append('self.%s("%s")' % (method, action[1]))
|
470
|
+
elif "'" not in action[1]:
|
471
|
+
sb_actions.append("self.%s('%s')" % (method, action[1]))
|
472
|
+
else:
|
473
|
+
sb_actions.append(
|
474
|
+
'self.%s("""%s""")' % (method, action[1])
|
475
|
+
)
|
466
476
|
elif action[0] == "da_el":
|
467
477
|
method = "deferred_assert_element"
|
468
478
|
if '"' not in action[1]:
|
469
479
|
sb_actions.append('self.%s("%s")' % (method, action[1]))
|
470
|
-
|
480
|
+
elif "'" not in action[1]:
|
471
481
|
sb_actions.append("self.%s('%s')" % (method, action[1]))
|
482
|
+
else:
|
483
|
+
sb_actions.append(
|
484
|
+
'self.%s("""%s""")' % (method, action[1])
|
485
|
+
)
|
472
486
|
elif action[0] == "da_ep":
|
473
487
|
method = "deferred_assert_element_present"
|
474
488
|
if '"' not in action[1]:
|
475
489
|
sb_actions.append('self.%s("%s")' % (method, action[1]))
|
490
|
+
elif "'" not in action[1]:
|
491
|
+
sb_actions.append("self.%s('%s')" % (method, action[1]))
|
476
492
|
else:
|
493
|
+
sb_actions.append(
|
494
|
+
'self.%s("""%s""")' % (method, action[1])
|
495
|
+
)
|
496
|
+
elif action[0] == "danet":
|
497
|
+
method = "deferred_assert_non_empty_text"
|
498
|
+
if '"' not in action[1]:
|
499
|
+
sb_actions.append('self.%s("%s")' % (method, action[1]))
|
500
|
+
elif "'" not in action[1]:
|
477
501
|
sb_actions.append("self.%s('%s')" % (method, action[1]))
|
502
|
+
else:
|
503
|
+
sb_actions.append(
|
504
|
+
'self.%s("""%s""")' % (method, action[1])
|
505
|
+
)
|
478
506
|
elif action[0] == "s_scr":
|
479
507
|
method = "save_screenshot"
|
480
508
|
if '"' not in action[1]:
|