@@ -3469,6 +3469,17 @@ def save_recorded_actions(self):
3469
3469
origin = self.get_origin()
3470
3470
self.__origins_to_save.append(origin)
3471
3471
tab_actions = self.__get_recorded_actions_on_active_tab()
3472
+ for n in range(len(tab_actions)):
3473
+ if (
3474
+ n > 2
3475
+ and tab_actions[n - 2][0] == "sw_fr"
3476
+ and tab_actions[n - 1][0] == "sk_fo"
3477
+ and tab_actions[n][0] != "_url_"
3478
+ ):
3479
+ origin = tab_actions[n - 2][2]
3480
+ time_stamp = str(int(tab_actions[n][3]) - 1)
3481
+ new_action = ["sw_pf", "", origin, time_stamp]
3482
+ tab_actions.append(new_action)
3472
3483
self.__actions_to_save.append(tab_actions)
3473
3484
3474
3485
def __get_recorded_actions_on_active_tab(self):
@@ -3478,6 +3489,7 @@ def __get_recorded_actions_on_active_tab(self):
3478
3489
or url.startswith("chrome:") or url.startswith("edge:")
3479
3490
):
3480
3491
return []
3492
+ self.__origins_to_save.append(self.get_origin())
3481
3493
actions = self.get_session_storage_item("recorded_actions")
3482
3494
if actions:
3483
3495
actions = json.loads(actions)
@@ -3492,34 +3504,43 @@ def __process_recorded_actions(self):
3492
3504
srt_actions = []
3493
3505
cleaned_actions = []
3494
3506
sb_actions = []
3495
- used_actions = []
3496
3507
action_dict = {}
3497
3508
for window in self.driver.window_handles:
3498
3509
self.switch_to_window(window)
3499
3510
tab_actions = self.__get_recorded_actions_on_active_tab()
3511
+ for n in range(len(tab_actions)):
3512
+ if (
3513
+ n > 2
3514
+ and tab_actions[n - 2][0] == "sw_fr"
3515
+ and tab_actions[n - 1][0] == "sk_fo"
3516
+ and tab_actions[n][0] != "_url_"
3517
+ ):
3518
+ origin = tab_actions[n - 2][2]
3519
+ time_stamp = str(int(tab_actions[n][3]) - 1)
3520
+ new_action = ["sw_pf", "", origin, time_stamp]
3521
+ tab_actions.append(new_action)
3500
3522
for action in tab_actions:
3501
- if action not in used_actions:
3502
- used_actions.append(action)
3523
+ if action not in raw_actions:
3503
3524
raw_actions.append(action)
3504
3525
for tab_actions in self.__actions_to_save:
3505
3526
for action in tab_actions:
3506
- if action not in used_actions:
3507
- used_actions.append(action)
3527
+ if action not in raw_actions:
3508
3528
raw_actions.append(action)
3509
3529
for action in self.__extra_actions:
3510
- if action not in used_actions:
3511
- used_actions.append(action)
3530
+ if action not in raw_actions:
3512
3531
raw_actions.append(action)
3513
3532
for action in raw_actions:
3514
- if self._reuse_session:
3515
- if int(action[3]) < int(self.__js_start_time):
3516
- continue
3533
+ if int(action[3]) < int(self.__js_start_time):
3534
+ continue
3517
3535
# Use key for sorting and preventing duplicates
3518
3536
key = str(action[3]) + "-" + str(action[0])
3519
3537
action_dict[key] = action
3520
3538
for key in sorted(action_dict):
3521
3539
# print(action_dict[key]) # For debugging purposes
3522
3540
srt_actions.append(action_dict[key])
3541
+ for n in range(len(srt_actions)):
3542
+ if srt_actions[n][0] == "sk_fo":
3543
+ srt_actions[n][0] = "sk_op"
3523
3544
for n in range(len(srt_actions)):
3524
3545
if (
3525
3546
(srt_actions[n][0] == "begin" or srt_actions[n][0] == "_url_")
@@ -3722,6 +3743,7 @@ def __process_recorded_actions(self):
3722
3743
ext_actions.append("s_c_d")
3723
3744
ext_actions.append("sh_fc")
3724
3745
ext_actions.append("c_l_s")
3746
+ ext_actions.append("c_s_s")
3725
3747
ext_actions.append("e_mfa")
3726
3748
ext_actions.append("ss_tl")
3727
3749
for n in range(len(srt_actions)):
@@ -4088,6 +4110,8 @@ def __process_recorded_actions(self):
4088
4110
sb_actions.append("self.%s()" % method)
4089
4111
elif action[0] == "c_l_s":
4090
4112
sb_actions.append("self.clear_local_storage()")
4113
+ elif action[0] == "c_s_s":
4114
+ sb_actions.append("self.clear_session_storage()")
4091
4115
elif action[0] == "c_box":
4092
4116
method = "check_if_unchecked"
4093
4117
if action[2] == "no":
@@ -5812,9 +5836,7 @@ def enter_mfa_code(
5812
5836
action = ["e_mfa", sel_key, origin, time_stamp]
5813
5837
self.__extra_actions.append(action)
5814
5838
# Sometimes Sign-In leaves the origin... Save work first.
5815
- self.__origins_to_save.append(origin)
5816
- tab_actions = self.__get_recorded_actions_on_active_tab()
5817
- self.__actions_to_save.append(tab_actions)
5839
+ self.save_recorded_actions()
5818
5840
mfa_code = self.get_mfa_code(totp_key)
5819
5841
self.update_text(selector, mfa_code + "\n", by=by, timeout=timeout)
5820
5842
@@ -6715,7 +6737,24 @@ def remove_session_storage_item(self, key):
6715
6737
6716
6738
def clear_session_storage(self):
6717
6739
self.__check_scope()
6718
- self.execute_script("window.sessionStorage.clear();")
6740
+ if not self.recorder_mode:
6741
+ self.execute_script("window.sessionStorage.clear();")
6742
+ else:
6743
+ recorder_keys = [
6744
+ "recorder_mode",
6745
+ "recorded_actions",
6746
+ "recorder_title",
6747
+ "pause_recorder",
6748
+ "recorder_activated",
6749
+ ]
6750
+ keys = self.get_session_storage_keys()
6751
+ for key in keys:
6752
+ if key not in recorder_keys:
6753
+ self.remove_session_storage_item(key)
6754
+ time_stamp = self.execute_script("return Date.now();")
6755
+ origin = self.get_origin()
6756
+ action = ["c_s_s", "", origin, time_stamp]
6757
+ self.__extra_actions.append(action)
6719
6758
6720
6759
def get_session_storage_keys(self):
6721
6760
self.__check_scope()
@@ -11634,9 +11673,9 @@ def setUp(self, masterqa_mode=False):
11634
11673
self._dash_initialized = True
11635
11674
self.__process_dashboard(False, init=True)
11636
11675
11637
- # Set the JS start time for Recorder Mode if reusing the session .
11676
+ # Set the JS start time for Recorder Mode.
11638
11677
# Use this to skip saving recorded actions from previous tests.
11639
- if self.recorder_mode and self._reuse_session :
11678
+ if self.recorder_mode:
11640
11679
self.__js_start_time = int(time.time() * 1000.0)
11641
11680
11642
11681
has_url = False
@@ -12417,18 +12456,23 @@ def has_exception(self):
12417
12456
def save_teardown_screenshot(self):
12418
12457
"""(Should ONLY be used at the start of custom tearDown() methods.)
12419
12458
This method takes a screenshot of the current web page for a
12420
- failing test (or when running your tests with --save-screenshot).
12459
+ FAILING test (or when using "--screenshot" / " --save-screenshot" ).
12421
12460
That way your tearDown() method can navigate away from the last
12422
12461
page where the test failed, and still get the correct screenshot
12423
12462
before performing tearDown() steps on other pages. If this method
12424
12463
is not included in your custom tearDown() method, a screenshot
12425
12464
will still be taken after the last step of your tearDown(), where
12426
12465
you should be calling "super(SubClassOfBaseCase, self).tearDown()"
12466
+ or "super().tearDown()".
12467
+ This method also saves recorded actions when using Recorder Mode.
12427
12468
"""
12428
12469
try:
12429
12470
self.__check_scope()
12430
12471
except Exception:
12431
12472
return
12473
+ if self.recorder_mode:
12474
+ # In case tearDown() leaves the origin, save actions first.
12475
+ self.save_recorded_actions()
12432
12476
if self.__has_exception() or self.save_screenshot_after_test:
12433
12477
test_logpath = os.path.join(self.log_path, self.__get_test_id())
12434
12478
self.__create_log_path_as_needed(test_logpath)
0 commit comments