我正在从事一个web自动化项目。这个项目是我个人的,因为我必须不断点击并填写网络应用程序(IBM Maximo Asset Management(上的文本字段。登录,然后单击我想去的链接最初工作得很好,但当我开始单击每一新行上的文本字段时,我会出现错误。就好像添加一个新行会改变整个DOM,但它只会在DOM中创建另一个表,而其他表则保持不变。如果可能的话,我很想有一个合作者帮我解决这个问题。
你会看到,在一些地方,由于自动化刚刚中断,我不得不使用完整的XPATH,例如:
if driver.find_element(
By.XPATH,
"/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":
如果没有完整的XPATH,代码就找不到这个元素。那么,我应该为所有元素使用完整的XPATH进行编码吗?请提出建议。
我觉得我应该为整个代码做这件事,但如果网络应用程序被更改或更新,这将使更改变得非常困难。
这是我的全部代码。
import datetime
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
# from selenium.webdriver.common.action_chains import ActionChains
options = webdriver.ChromeOptions()
prefs = {"download.default_directory": "C:\Users\Administrator\Desktop\NewWO\NEW"}
options.add_experimental_option("prefs", prefs)
PATH = "C:\Users\Administrator\Desktop\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(PATH, options=options)
# Wait 3 seconds for the "chromedriver.exe" to load
time.sleep(3)
action = ActionChains(driver)
# Open IBM MAXIMO Asset Management Web App
driver.get("http://10.1.84.87/maximo/webclient/login/login.jsp?appservauth=true")
driver.maximize_window()
# Wait 2 seconds for login elements to load
time.sleep(4)
# Login to IBM Maximo Asset Management
# Pass login parameters
with open("C:\Users\Administrator\Desktop\WO_Automation\pass.txt", "r") as p:
maximo_pass_supervisor = p.read()
id_box = driver.find_element(By.ID, 'j_username')
id_box.send_keys("07780141")
pass_box = driver.find_element(By.ID, 'j_password')
pass_box.send_keys(maximo_pass_supervisor)
pass_box.submit()
# Click on "Work Order Tracking" link after login
element_wo_tracking = WebDriverWait(driver, 600).until(
ec.visibility_of_element_located((By.LINK_TEXT, "Work Order Tracking")))
wo_track = driver.find_element(By.LINK_TEXT, "Work Order Tracking")
wo_track.click()
time.sleep(3)
# Create a list of arguments to be entered into fields based on the 'description.txt' file
pm_actuals = []
with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_number:
pm = pm_number.readlines()[11:12]
for line in pm:
line = line.upper().strip().split(",")
pm_actuals.append(line)
# A function to send text to an element one character at a time with a delay of 0.1s
def slow_type(el, text, delay=0.1):
for character in text:
el.send_keys(character)
time.sleep(delay)
# Check for PM availability
pm_availability = []
for pm in range(0, len(pm_actuals[0])):
time.sleep(1)
ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
search_text_wo.clear()
slow_type(search_text_wo, pm_actuals[0][pm].replace(" ", "", 1))
search_text_wo.send_keys(Keys.RETURN)
element_len_elements_list = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.visibility_of_any_elements_located((By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")))
len_elements_list = driver.find_elements(By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")
if len(len_elements_list) != 0:
# Check if PM status is WSCH
if driver.find_element(
By.XPATH,
"/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":
pm_availability.append(pm_actuals[0][pm].replace(" ", "", 1))
continue
# If PM status is not WSCH, continue searching
else:
continue
else:
continue
# Exceptions to ignore
ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
# Start PM routing
counter = 0
while len(pm_availability) != 0:
for i in range(0, len(pm_availability)):
element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
search_text_wo.clear()
slow_type(search_text_wo, pm_availability[i])
search_text_wo.send_keys(Keys.RETURN)
# Start PM routing procedure if the status is WSCH
# Select the PM
element_first_row_search = WebDriverWait(driver, 600, 5, ignore_exceptions).until(
ec.presence_of_element_located(
(By.XPATH,
"/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[3]/span[@id='m6a7dfd2f_tdrow_[C:1]_ttxt-lb[R:0]']")))
first_row = driver.find_element(
By.XPATH, "/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[3]/span[@id='m6a7dfd2f_tdrow_[C:1]_ttxt-lb[R:0]']")
first_row.click()
time.sleep(3)
# Go to ACTUALS tab
element_actuals_tab = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='m272f5640-tab']")))
actuals_tab = driver.find_element(By.XPATH, "//*[@id='m272f5640-tab']")
actuals_tab.click()
# Create a list of all labor information
pm_labor = []
with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_info:
pm = pm_info.readlines()[14:]
for line in pm:
line = line.upper().strip().split(",")
pm_labor.append(line)
# Create a list of duration to calculate the PM start and end times
duration = []
with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_duration:
pm = pm_duration.readlines()[8:9]
for line in pm:
line = line.upper().strip().split(".")
duration.append(line)
# Create a list for the start_time_pm values
starting_time = []
with open("C:\Users\Administrator\Desktop\PM.txt", "r") as pm_start:
start = pm_start.readlines()[3:5]
for line in start:
line = line.upper().strip().split("=")
starting_time.append(line)
# Start time for all PMs will be 0700 hours
start_time_pm = datetime.timedelta(hours=int(starting_time[0][1]),
minutes=int(starting_time[1][1]), seconds=0)
# Create a list of times based on the duration of PM in PM.txt file
start_time = []
end_time = []
# Iterate the time starting from 0700 hours to create PM time slots
while start_time_pm < datetime.timedelta(hours=14, minutes=0):
end_time_pm = start_time_pm + datetime.timedelta(hours=int(duration[0][0])) +
datetime.timedelta(minutes=int(duration[0][1]))
# If end time is 1415 hours or less, append the time values to the lists
if end_time_pm <= datetime.timedelta(hours=14, minutes=15):
start_time.append(str(start_time_pm))
end_time.append(str(end_time_pm))
start_time_pm = start_time_pm + datetime.timedelta(hours=int(duration[0][0])) +
datetime.timedelta(minutes=int(duration[0][1])) +
datetime.timedelta(minutes=15)
# If end time is 1400 hours or more, break out of the loop
elif end_time_pm >= datetime.timedelta(hours=14, minutes=0):
break
else:
continue
time.sleep(2)
# Add labor information
for labor_row in range(0, len(pm_labor)):
try:
# Click on new labor for a new row to enter labor information
element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
new_labor.click()
time.sleep(2)
# Add labor ID from pm_labour list
element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
labor_id = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
labor_id.clear()
slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
time.sleep(2)
# Add start date for PM from pm_labour list
element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
start_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
start_date.clear()
slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add end date for PM from pm_labour list
element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
end_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
end_date.clear()
slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add start time for PM from start_time list
element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
start_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
start_time_text.clear()
slow_type(start_time_text, start_time[counter])
time.sleep(2)
# Add end time for PM from end_time list
element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
end_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
end_time_text.clear()
slow_type(end_time_text, end_time[counter])
time.sleep(3)
except StaleElementReferenceException:
# Delete row if exception is thrown and continue with loop
element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
driver.find_element(
By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
if labor_row == 0:
labor_row = 0
continue
else:
labor_row += 0
continue
# If labor rows are filled, then route the PM work order
for rout in range(0, 3):
if driver.find_element(By.XPATH, "//*[@id='md489b5d4-tb']").text != "COMP":
# Click on the route button
element_route = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")))
route = driver.find_element(By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")
route.click()
time.sleep(5)
# Click on OK in the corresponding dialog box
# element_click_ok = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
# ec.element_to_be_clickable((By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")))
#
# click_ok = driver.find_element(By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")
#
# click_ok.click()
driver.switch_to.alert.accept()
time.sleep(5)
else:
pass
# Once the PM work order is routed, go back to search field
element_list_view = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.visibility_of_element_located((By.XPATH,
"//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")))
list_view = driver.find_element(By.XPATH,
"//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")
time.sleep(2)
list_view.click()
time.sleep(2)
pms_routed = [print(f"WO {pm_actuals[0][i]} is closed.")]
counter += 1
time.sleep(2)
len(pm_availability) - 1
# Log out and quit
element_logout = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH,
"//div[@id='m4cd0065c-co_0_div']//*[@id='titlebar_hyperlink_8-co_0']//*[@id='titlebar_hyperlink_8-lbsignout']"))
)
logout = driver.find_element(
By.XPATH,
"//div[@id='m4cd0065c-co_0_div']//*[@id='titlebar_hyperlink_8-co_0']//*[@id='titlebar_hyperlink_8-lbsignout']")
logout.click()
time.sleep(2)
element_quit = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.visibility_of_element_located((By.XPATH, "//*[@id='returnFrm']//*[@id='submit']")))
return_login = driver.find_element(By.XPATH, "//*[@id='returnFrm']//*[@id='submit']")
return_login.click()
time.sleep(2)
driver.quit()
我做错什么了吗?我使用了一个"try-except"块,但还没能测试它,但如果"try-eexcept"是这样编码的,我希望得到反馈。我在手动工作时检查了DOM,除了创建新行或向工作订单添加内容时,DOM并没有真正改变。
这是"尝试除外"块:
for labor_row in range(0, len(pm_labor)):
try:
# Click on new labor for a new row to enter labor information
element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
new_labor.click()
time.sleep(2)
# Add labor ID from pm_labour list
element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
labor_id = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
labor_id.clear()
slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
time.sleep(2)
# Add start date for PM from pm_labour list
element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
start_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
start_date.clear()
slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add end date for PM from pm_labour list
element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
end_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
end_date.clear()
slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add start time for PM from start_time list
element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
start_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
start_time_text.clear()
slow_type(start_time_text, start_time[counter])
time.sleep(2)
# Add end time for PM from end_time list
element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
end_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
end_time_text.clear()
slow_type(end_time_text, end_time[counter])
time.sleep(3)
except StaleElementReferenceException:
# Delete row if exception is thrown and continue with loop
element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
driver.find_element(
By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
if labor_row == 0:
labor_row = 0
continue
else:
labor_row += 0
continue
错误主要是:
StaleElementException: element is not attached to page'
发生错误的具体部分是:
(有时错误是在第一次迭代中抛出的,或者在前几次迭代中它会很好地工作,然后再次中断,这更令人沮丧!(
1.
pm_availability = []
for pm in range(0, len(pm_actuals[0])):
time.sleep(1)
ignore_exceptions = (NoSuchElementException, StaleElementReferenceException,)
element_search_text_wo = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.visibility_of_element_located((By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")))
search_text_wo = driver.find_element(By.XPATH, "//input[@id='m6a7dfd2f_tfrow_[C:1]_txt-tb']")
search_text_wo.clear()
slow_type(search_text_wo, pm_actuals[0][pm].replace(" ", "", 1))
action.move_to_element(search_text_wo).send_keys(Keys.RETURN).release().perform()
element_len_elements_list = WebDriverWait(driver, 120, 5, ignore_exceptions).until(
ec.visibility_of_any_elements_located((By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")))
len_elements_list = driver.find_elements(By.XPATH, "//*[contains(@id, 'm6a7dfd2f_tbod_tdrow-tr[R:')]")
if len(len_elements_list) != 0:
# Check if PM status is WSCH
if driver.find_element(
By.XPATH,
"/html/body/form/div/table[2]/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr[2]/td/div/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr/td/div/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/div/table/tbody/tr[3]/td/table/tbody/tr[3]/td/table/tbody/tr[4]/td[10]").text == "WSCH":
pm_availability.append(pm_actuals[0][pm].replace(" ", "", 1))
continue
# If PM status is not WSCH, continue searching
else:
continue
else:
continue
for labor_row in range(0, len(pm_labor)):
try:
# Click on new labor
element_new_labor = WebDriverWait(driver, 60, 5, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")))
new_labor = driver.find_element(By.XPATH, "//*[@id='m4dfd8aef_bg_button_addrow-pb']")
new_labor.click()
time.sleep(2)
# Add labor ID from pm_labour list
element_labor_id = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")))
labor_id = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:2]_txt-tb[R:" + str(labor_row) + "]']")
labor_id.clear()
slow_type(labor_id, pm_labor[labor_row][0].replace(" ", "", 1))
time.sleep(2)
# Add start date for PM from pm_labour list
element_start_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")))
start_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:6]_txt-tb[R:" + str(labor_row) + "]']")
start_date.clear()
slow_type(start_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add end date for PM from pm_labour list
element_end_date = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable((
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")))
end_date = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:7]_txt-tb[R:" + str(labor_row) + "]']")
end_date.clear()
slow_type(end_date, pm_labor[labor_row][1].replace(" ", "", 1))
time.sleep(2)
# Add start time for PM from start_time list
element_start_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")))
start_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:8]_txt-tb[R:" + str(labor_row) + "]']")
start_time_text.clear()
slow_type(start_time_text, start_time[counter])
time.sleep(2)
# Add end time for PM from end_time list
element_end_time = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")))
end_time_text = driver.find_element(
By.XPATH, "//input[@id='m4dfd8aef_tdrow_[C:9]_txt-tb[R:" + str(labor_row) + "]']")
end_time_text.clear()
slow_type(end_time_text, end_time[counter])
time.sleep(3)
except StaleElementReferenceException:
element_delete_row = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.element_to_be_clickable(
(By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']")))
driver.find_element(
By.XPATH,
"//*[@id='m900f2d81_tdrow_[C:9]_toggleimage-ti[R:" + str(labor_row) + "]']").click()
if labor_row == 0:
labor_row = 0
continue
else:
labor_row += 0
continue
for rout in range(0, 3):
if driver.find_element(By.XPATH, "//*[@id='md489b5d4-tb']").text != "COMP":
# Click on the route button
element_route = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
ec.element_to_be_clickable((By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")))
route = driver.find_element(By.XPATH, "//*[@id='ROUTEWF_KAUWO_-tbb_anchor']")
route.click()
time.sleep(5)
# Click on OK in the corresponding dialog box
# element_click_ok = WebDriverWait(driver, 180, 20, ignore_exceptions).until(
# ec.element_to_be_clickable((By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")))
#
# click_ok = driver.find_element(By.XPATH, "//button[@type='button' and @id='md875c1f9-pb']")
#
# click_ok.click()
driver.switch_to.alert.accept()
time.sleep(5)
else:
pass
element_list_view = WebDriverWait(driver, 30, 5, ignore_exceptions).until(
ec.visibility_of_element_located((By.XPATH,
"//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")))
list_view = driver.find_element(By.XPATH,
"//*[@id='m397b0593-tabs_backToList']/table/tbody/tr/td[1]")
time.sleep(2)
list_view.click()
time.sleep(2)
pms_routed = [print(f"WO {pm_actuals[0][i]} is closed.")]
counter += 1
time.sleep(2)
len(pm_availability) - 1
StaleElementException: element is not attached to page
意味着元素的先前引用现在已经过时,并且元素引用不再存在于页面的HTML DOM的当前状态中。
此异常背后的常见原因可能是以下任一原因:
- 元素已经改变了它在HTML DOM中的位置
- 元素不再附加到DOM树
- 元素所在的网页已刷新
- 元素的上一个实例已由JavaScript刷新
此用例
您的怀疑"when I start clicking on text fields on each new row that I get errors. It's as if adding a new row changes the whole DOM"
是绝对正确的,因为"creates another table in the DOM"
肯定会更改DOM树中先前标识的元素的位置,尽管其他元素保持不变。
参考文献
您可以在中找到一些相关的详细讨论
- PageFactory中的StaleElementReference异常