【问题标题】:I want to get orderID from API response using selenium python我想使用 selenium python 从 API 响应中获取 orderID
【发布时间】:2022-01-21 06:43:57
【问题描述】:

我想从 API 响应中获取订单 ID。当我点击 Create Order 按钮时,它会发送一个 POST API 请求并返回我想要的唯一 ID。

这是我的订单创建代码。

from datetime import date
import time
from seleniumwire import webdriver
from openpyxl import load_workbook
from Locators.PracticeLocators import PracticeLocators
from pageObjects.LoginPage import LoginScreen

today = date.today()
currentDate = today.strftime("%m/%d/%Y")
FilePath = "C:/Users/Administrator/PycharmProject/LegrandePython/TestData/Data.xlsx"
datafile = load_workbook(FilePath)
testData = datafile['Test Data']
loginData = datafile["Login Credentials"]
scriptData = datafile["Script Data"]

driver = webdriver.Chrome(executable_path="C:/Users/Administrator/Downloads/chromedriver.exe")
driver.maximize_window()

driver.scopes = [
    '.*https://ibis-dev.droicelabs.us/api/dispenser/orders/.*'
]

driver.get(loginData.cell(4, 2).value)
driver.implicitly_wait(5)
login = LoginScreen(driver)
login.SetUsername(loginData.cell(4, 3).value)
login.SetPassword(loginData.cell(4, 4).value)
login.SignIn()
driver.implicitly_wait(20)
driver.find_element_by_class_name(PracticeLocators.Add_RX).click()
PatientSearch = driver.find_element_by_xpath(PracticeLocators.Patient_search_textbox)
PatientSearch.click()
PatientSearch.send_keys(testData.cell(2, 1).value)
driver.find_element_by_xpath("(//*[text()='" + testData.cell(2, 2).value + "'])[1]").click()
DoctorSearch = driver.find_element_by_xpath(PracticeLocators.doctor_search_textbox)
DoctorSearch.click()
time.sleep(1)
DoctorSearch.send_keys(scriptData.cell(2, 8).value)
time.sleep(1)
driver.find_element_by_xpath(
    "(//*[text()='" + scriptData.cell(2, 8).value + " " + "Practice'])[2]").click()
driver.find_element_by_xpath(PracticeLocators.NextButton).click()
driver.find_element_by_xpath(PracticeLocators.CreateOnetimeRXButton).click()
driver.find_element_by_name(PracticeLocators.OnetimeSearchMedicine).send_keys(scriptData.cell(2, 1).value)
time.sleep(2)
driver.find_element_by_xpath("//*[text()='" + scriptData.cell(2, 1).value + "']").click()
driver.find_element_by_xpath(PracticeLocators.AddButton).click()
driver.find_element_by_xpath(PracticeLocators.ProductQuantity).click()
time.sleep(1)
driver.find_element_by_xpath(PracticeLocators.Quantity).click()
driver.find_element_by_xpath(PracticeLocators.ProductRefilles).click()
time.sleep(1)
driver.find_element_by_xpath(PracticeLocators.Quantity).click()
time.sleep(2)
driver.find_element_by_xpath(PracticeLocators.DAWCheckbox).click()
time.sleep(2)
instruction = driver.find_element_by_xpath(PracticeLocators.productInstruction)
instruction.click()
instruction.send_keys(testData.cell(2, 3).value)
driver.find_element_by_xpath(PracticeLocators.allergiesButton).click()
allergies = driver.find_element_by_xpath(PracticeLocators.allergiesTextbox)
allergies.clear()
allergies.send_keys(testData.cell(2, 4).value)
driver.find_element_by_xpath(PracticeLocators.doneButton).click()
driver.find_element_by_xpath(PracticeLocators.addDropchartButton).click()
time.sleep(2)
element = driver.find_element_by_xpath(PracticeLocators.selectDocuments)
driver.execute_script("arguments[0].click()", element)
driver.find_element_by_xpath(PracticeLocators.selectButton).click()
driver.find_element_by_xpath(PracticeLocators.skipPayment).click()
driver.find_element_by_xpath(PracticeLocators.surgeryDate).send_keys(currentDate)
createOrderButton = driver.find_element_by_xpath(PracticeLocators.submit_CreateOrderButton)
driver.execute_script("arguments[0].click()", createOrderButton)
for request in driver.requests:
    if request.response:
        print(
            request.url,
            request.response.status_code,
            request.response.headers['Content-Type'])
time.sleep(7)

self.driver.execute_script("arguments[0].click()", createOrderButton) 这行执行时,它将发送POST API https://ibis-dev.droicelabs.us/api/dispenser/orders/ 并返回我想要的唯一订单ID。

我已经给出了范围,但它会返回许多 API 调用

driver.scopes = [
    '.*https://ibis-dev.droicelabs.us/api/dispenser/orders/.*'
]

https://ibis-dev.droicelabs.us/api/dispenser/orders/ 当我单击创建订单按钮并返回订单 ID 时,将调用此 API。 它不会显示我在范围中使用的 API。以及如何获得我在范围内给出的那个 API 的响应。 我是 selenium python 的新手,我已经在 cypress 中完成了它。但不知道如何使用 selenium python。

【问题讨论】:

    标签: python selenium web-api-testing data-driven-tests


    【解决方案1】:

    这是使用 Selenium 捕获 HTTP 请求的方法:

    1 安装包

    pip install selenium-wire 
    

    2 使用driver.requests 获取一些数据

    from seleniumwire import webdriver
    
    driver = webdriver.Chrome()
    
    # do you actions with driver
    
    for request in driver.requests:  
        if request.response:  
            print(  
                request.url,  
                request.response.status_code,  
                request.response.headers['Content-Type'])  
    

    3 您可能希望将请求捕获限制到某些特定主机

    https://pypi.org/project/selenium-wire/#limiting-request-capture

    driver.scopes = [
        '.*ibis-dev.droicelabs.us/api/dispenser/orders/.*'
    ]
    

    4 如何阅读响应正文

    import json
    
    ...
    
        for request in driver.requests:
            if request.response:
                data = json.loads(request.response.body)
                print(data['foo'])
    

    回答这个问题 - 获取订单 ID

    获取处理UnicodeDecodeErrorJSONDecodeError 错误并打印一些调试详细信息的多个门户的order_id 的最终解决方案:

    #define scopes to capture the required requests
    driver.scopes = [
        '.*/api/dispenser/orders/.*',
        '.*/api/practice/orders/.*',
        '.*/api/practice/subscriptions/.*'
    ]
    
    
    # UI steps performed...
    
    # The last UI action
    createOrderButton = driver.find_element_by_xpath(PracticeLocators.submit_CreateOrderButton)
    driver.execute_script("arguments[0].click()", createOrderButton)
    time.sleep(5)
    
    order_id = None
    # read requests for order_id
    for request in driver.requests:
        if request.response:
            if request.method == 'POST':
                print(request.method + ' ' + request.url)
                try:
                    data = json.loads(request.response.body)
                    print('parsed as json')
                    if '_id' in data:
                        order_id = data['_id']
                except UnicodeDecodeError:
                    try:
                        data = json.loads(decompress(request.response.body))
                        print('decompressed and parsed as json')
                        if '_id' in data:
                            order_id = data['_id']
                    except json.decoder.JSONDecodeError:
                        data = request.response.body
                        print('decompressed and parsed as string')
    print(data)
    print(order_id)
    

    限制

    Selenium Wire 目前可用于与浏览器在同一台机器上运行的测试。尚不支持使用 Selenium Grid 的分布式设置。

    目前无法使用 Selenium Wire 测试使用 NTLM 身份验证(Windows 身份验证)的站点。不支持 NTLM 身份验证。


    参考

    https://pypi.org/project/selenium-wire/

    【讨论】:

    • for request in self.driver.requests: 这一行中获取AttributeError: 'WebDriver' object has no attribute 'requests' 不起作用。
    • 你使用什么导入? from selenium import webdriverfrom seleniumwire import webdriver?
    • 我用过from seleniumwire import webdriver
    • 此错误与您的实现有关,因为我提供的纯示例运行良好。我已经重新检查过.. 错误AttributeError: 'WebDriver' object has no attribute 'requests' 表示您在此字段中有一些“WebDriver”对象,但它不是 seleniumwire WebDriver。尝试打印print(type(self.driver))
    • @KrupalVaghasiya 你也必须使用本地网络驱动程序,而不是远程。我已经更新了限制部分的答案。
    猜你喜欢
    • 1970-01-01
    • 2022-01-11
    • 2021-06-12
    • 2018-05-21
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多