【发布时间】:2018-06-06 18:51:12
【问题描述】:
目前我正在尝试自动化订单流程,并且在某些时候,如果最近下过订单,则会弹出一条警报,指出“客户已在 2 天内为这些相同的商品下订单。请检查对于重复项或选中覆盖重复顺序以继续。”
我尝试了以下方法来拦截该警报并允许脚本继续运行:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.support import expected_conditions as ExCon
from selenium.common.exceptions import TimeoutException, NoSuchElementException, NoAlertPresentException,\
UnexpectedAlertPresentException
from oleaprocs import Order
"""
Will put the following constants in their own file later
"""
GEN_NEXT_ID = "cmdNext"
SHIP_DET_METH_ID = "cboAvailItemsShip"
SHIP_DET_NEXT_ID = "cmdNext"
ORDER_REP_ID = "cboServiceRep"
EMAIL_ID = "ctl00_ctl00_main_content_main_content_ctl00_txtEmail"
SEARCH_RESULT_ID = "ctl00_ctl00_main_content_main_content_ctl00_dgResults_ctl03_lnkCustName"
ADD_ORDER_ID = "cmdAddNewOrder"
LOGIN_ID = 'ctl00_ctl00_main_content_main_content_ctl00_UserName'
PASS_ID = 'ctl00_ctl00_main_content_main_content_ctl00_password'
SIGNIN_ID = 'ctl00_ctl00_main_content_main_content_ctl00_SigninBtn'
PLACED_VIA = 'Phone'
BILL_OPTION = 'Visa x1111'
username = 'user'
password = 'pass'
customer = 'user'
items = {'Item1': '100', 'Item2': '125'} # One or many items - also noting quantity
# This setup will likely be steamlined to determine whose server to use, etc
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("website-placeholder-for-security-reasons")
# Login will be separated out into a function, to allow for various logins
# log-in
driver.find_element_by_id(LOGIN_ID).send_keys(username)
driver.find_element_by_id(PASS_ID).send_keys(password)
driver.find_element_by_id(SIGNIN_ID).click()
driver.find_element_by_xpath('//a[text()="Customers"]').click()
# Type in search for user-email - separated to function later
search_email = driver.find_element_by_id(EMAIL_ID)
search_email.send_keys(customer)
search_email.send_keys(Keys.RETURN)
# Click the (hopefully) singular search result
driver.find_element_by_id(SEARCH_RESULT_ID).click()
#search_result = driver.find_element_by_id(SEARCH_RESULT_ID).click()
#search_result.click()
### Start creating new order ###
## Order Items ##
# Accept Customer Orders alert
"""
alert_obj = driver.switch_to.alert
alert_obj.accept()
"""
Alert(driver).accept()
# Click on "Add New Order"
driver.find_element_by_id(ADD_ORDER_ID).click()
order = Order(driver)
# Set Placed Via
placed_via = Select(driver.find_element_by_name('cboPlacedVia'))
placed_via.select_by_visible_text(PLACED_VIA) # could also set IDs in a dict
# Set Billing Option
bill_option = Select(driver.find_element_by_name('ctrlBillOption$cboBillOption'))
bill_option.select_by_visible_text(BILL_OPTION)
# Add items to order
order.add_items(items)
# Will likely do some assertions here at some point, for custom / printed items
driver.find_element_by_id('cmdNext').click()
## Shipping Details ##
# Select Shipping Method
# If similar order recently placed - confirm alert and try/except duplicate order override
# driver.implicitly_wait(2)
try:
print("WebDriverWait - 2 seconds")
WebDriverWait(driver, 2).until(ExCon.alert_is_present())
Alert(driver).accept()
print("Switching to Alert")
#alert_dupe = driver.switch_to.alert
# print(str(alert_dupe.text))
# alert_dupe.accept()
except TimeoutException:
print("Timeout")
except NoAlertPresentException:
print("No Alert Present")
except UnexpectedAlertPresentException:
print("Unexpected alert, yo!")
try:
driver.find_element_by_id('chkDuplicateOrderOverride').click()
except NoSuchElementException:
print("No duplicate order detected")
# Continue
driver.find_element_by_id('cmdNext').click()
## Order Group Details ##
# Check for Authorize button (I could bypass this when I implement "order_type" later
try:
driver.find_element_by_id('cmdAuthorize').click()
except NoSuchElementException:
print("No Authorize Element Found - This payment method does not require authorization")
driver.find_element_by_id('cmdPlaceOrder').click()
以及引用的其他文件:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
"""
Order will be used to keep track of the state of an order throughout
the order-process. This can include things like the order total, items
included, and can even get as complicated as 1:1 mirroring all of the
details of an order. This will depend on our requirements.
"""
class Order(object):
def __init__(self, driver):
self.driver = driver
# self.product_name_field = self.driver.find_element_by_id('txtProductName')
# self.quantity_field = self.driver.find_element_by_id('txtQuantity')
# self.add_item_button = self.driver.find_element_by_id('cmdAddSaveItem')
# Add items to an order
def add_items(self, items):
"""
Will need to make the quantity check in here.
"""
# product_name_field = self.driver.find_element_by_id('txtProductName')
# quantity_field = self.driver.find_element_by_id('txtQuantity')
# add_item_button = self.driver.find_element_by_id('cmdAddSaveItem')
"""
Cannot simply one-time set the above because of the references
going stale x_x - need to see if I can ignore stale-references.
"""
for item, quantity in items.items():
product_name_field = self.driver.find_element_by_id('txtProductName')
product_name_field.send_keys(item)
product_name_field.send_keys(Keys.TAB)
quantity_field = self.driver.find_element_by_id('txtQuantity')
quantity_field.send_keys(quantity)
quantity_field.send_keys(Keys.TAB)
add_item_button = self.driver.find_element_by_id('cmdAddSaveItem')
add_item_button.click()
我对上一个警报可能不会释放资源进行了评论...我有以下代码早一点处理一个 总是 弹出的警报,所以我不必try那个:
alert_obj = driver.switch_to.alert
alert_obj.accept()
我在这里使用driver.switch_to.alert 变体,因为我在早期代码中尝试了两种变体,但均未奏效。
当代码到达WebDriverWait(drive, 2)... 时,基本上会发生什么,浏览器会坐在那里等待 2 秒,然后会弹出警报。我尝试了各种任意长度的时间,它总是会等待那个时间,然后显示警报。我觉得我在这里被拖了:|
这是发生这种情况后我收到的错误信息:
Traceback (most recent call last):
File "C:\Users\user\Documents\Projects\Selenium\proj.py", line 136, in <module>
driver.find_element_by_id('cmdAuthorize').click()
File "C:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 353, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "C:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 957, in find_element
'value': value})['value']
File "C:\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 314, in execute
self.error_handler.check_response(response)
File "C:\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 241, in check_response
raise exception_class(message, screen, stacktrace, alert_text)
selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: None
Message: unexpected alert open: {Alert text : Customer has placed an order for these same items within 2 days. Please check for duplicates or check Override Duplicate Order to continue.}
(Session info: chrome=66.0.3359.181)
(Driver info: chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Windows NT 10.0.16299 x86_64)
知道为什么会发生这种情况吗?如果我没记错的话,我不相信我们真的有任何警报也有复选框或输入,所以我不会 100% 反对仅仅 100% 阻止警报被 Selenium 确认(或自动接受它们),但如果可以的话,我想避免这种情况。
如果最近没有下订单(或者我使用不同的帐户一遍又一遍地测试订单创建),代码运行完全正常,并且一直正确下订单。
从添加项目(就在有问题的页面之前)开始的手动步骤是:
1) 输入商品名称,然后输入商品数量 2)对“项目”字典中的每个项目执行此操作 3)点击下一步按钮 4) 带有运输选项的下一页“装载” 5) 如果最近下订单会出现问题——WebDriverWait 似乎正在停止页面的加载?似乎是这种情况,因为警报直到 WebDriverWait 时间用完后才会显示。
在告诉 Selenium 点击下一步按钮进入下一页后,我并没有真正做任何特别的事情。与之前的“点击下一个按钮”操作没有什么不同,并且该页面的行为实际上应该与其他页面没有任何不同 - 即使警报显然只是没有它 x_x
【问题讨论】:
-
您的代码是
driver.find_element_by_id('chkDuplicateOrderOverride').click(),但回溯显示driver.find_element_by_id('cmdAuthorize').click()...我错过了什么吗? -
对吗?超级诡异。所以显然它......只是跳过一堆东西并继续下一段代码,我也不知道为什么会发生这种情况。但它肯定会停在那里,因为在“cmdAuthorize”阶段,我们已经在下一页,所以它自然会尝试引用不存在的东西。由于“给自己的笔记”等原因,目前有点混乱,但如果您认为这有帮助,我可以发布所有代码。
-
IMO 太多
try{}和catch{}行为不端。你能用更多的用例(手动步骤)和代码尝试来更新这个问题吗? -
更新了完整的代码和过程中手动步骤的一些说明。有点(我想)直截了当,但我们在这里......
标签: python selenium exception alert