Python Selenium - Как обрабатывать оповещения, которые не появляются до тех пор, пока WebDriverWait не завершится? - PullRequest
0 голосов
/ 06 июня 2018

В настоящее время я пытаюсь автоматизировать процесс заказа, и в какой-то момент, если заказ был недавно размещен, появится всплывающее предупреждение: «Клиент разместил заказ на эти же товары в течение 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 секунды, THEN , появляется предупреждение.Я пробовал разные произвольные отрезки времени, и он всегда будет ждать это количество времени, а затем показывать предупреждение.Я чувствую, что меня здесь троллируют: |

Вот информация об ошибке, которую я получаю после того, как это произойдет:

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)Сделайте это для каждого элемента в поле «items». 3) Нажмите следующую кнопку. 4) Следующая страница с опциями доставки «загружается». 5) Проблема возникает, если заказ был недавно размещен - кажется, что WebDriverWait останавливает загрузку страницы.?Похоже, что это так, поскольку предупреждение не будет отображаться до тех пор, пока не истечет время ожидания WebDriver.

На самом деле я ничего особенного не делаю после того, как сказал Selenium нажать следующую кнопку, чтобы перейти на следующую страницу.Ничего не отличается от предыдущих действий "нажать следующую кнопку", и страница не должна вести себя иначе, чем другие страницы - даже если в предупреждении, по-видимому, просто нет x_x

1 Ответ

0 голосов
/ 07 июня 2018

У меня не было «кнопки« Далее »до проверки оповещения» - предупреждение не появляется до после . Я пытаюсь отправить сведения о доставке сначала .Причина, по которой он, похоже, перешел к дальнейшим действиям после сбоя проверки оповещения.

Предварительно изложите процесс, дети.

...