感谢所有看到此问题的人。我单击一个按钮以触发执行使用此功能中的selenium
来创建driver
的功能。
使用此驱动程序,我可以拖放图片,单击按钮,将SMS验证码发送到手机,而无需打开Firefox浏览器窗口。
全部结束后,我需要跳过一个向导来让用户输入发送到手机的验证码。但是,从odoo界面加载向导并输入验证码并单击确认按钮后,我需要输入将验证码值添加到我刚刚用driver
打开的页面中。
如何获取上一个driver
?谢谢,有什么好的解决方案。
这是我使用selenium
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
import selenium
from selenium.webdriver.firefox.options import Options
import time
from selenium.webdriver import ActionChains
class SaleOrderSend(models.Model)
_name='sale.order.send'
@api.multi
def handel_web_send_captcha(self):
options = Options()
options.add_argument('--headless')
driver = selenium.webdriver.Firefox(options=options)
driver.get(sign_url)
time.sleep(15)
ac1 = driver.find_elements_by_class_name("es-drag-seal")[0]
ac2 = driver.find_element_by_class_name('es-sign-date-field')
time.sleep(1)
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
time.sleep(2)
submit_button = driver.find_element_by_xpath("//button//span[text()='Submit']")
submit_button.click()
time.sleep(3)
driver.switch_to.frame(0)
short_message = driver.find_element_by_xpath("//a[text()='Sign']")
short_message.click()
time.sleep(3)
send_code = driver.find_element_by_xpath("//div[@class='el-form-item__content']//button//span[text()='Get_Code']")
send_code.click()
time.sleep(2)
driver.close()
action = {
'name': _("Please enter the verification code"),
'type': 'ir.actions.act_window',
'res_model': 'signature.code',
'view_type': 'form',
'view_mode': 'form',
'target': 'new'
}
return action
这是我在向导中的py文件和xml文件
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
import selenium
from selenium.webdriver.firefox.options import Options
import time
from selenium.webdriver import ActionChains
class SignatureCode(models.Model):
_name = 'signature.code'
_description = 'Signature Code'
sign_code = fields.Char('Sign Code')
sign_url = fields.Char('Sign Url')
@api.multi
def confirm_sign_code(self):
"""
Enter the user's captcha code into the browser page you just opened using selenium.
:return:
"""
sign_code = self.sign_code
# How do I get to the previous driver? driver = selenium.webdriver.Firefox(options=options)
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="signature_code_form_view" model="ir.ui.view">
<field name="name">Signature Code Form View</field>
<field name="model">signature.code</field>
<field name="arch" type="xml">
<form string="Signature Code Form View">
<sheet>
<group>
<group>
<field name="sign_code" required="1" readonly="0"/>
</group>
</group>
</sheet>
<footer>
<button string="Confirm" name="confirm_sign_code" type="object" default_focus="1"
class="btn-primary"/>
<button string="Cancel" class="btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>
答案 0 :(得分:0)
pychong
在此方法上def handel_web_send_captcha(self)
像这样添加了code
,
ctx = self.env.context.copy()
ctx.update({'previous_driver': driver})
action = {
'name': _("Please enter the verification code"),
'type': 'ir.actions.act_window',
'res_model': 'signature.code',
'view_type': 'form',
'view_mode': 'form',
'target': 'new',
'context': ctx,
}
在这种def confirm_sign_code(self)
方法上,像这样获取以前的驱动程序数据,
driver = self._context.get('previous_driver')
print("\n\n driver ", driver)
谢谢
答案 1 :(得分:0)
使用Python的类属性存储已经生成的驱动程序。
在操作中,我们首先单击一个按钮以跳到向导,其中有两个按钮。
首先单击第一个按钮以触发方法send_code
,在其中我们修改类属性,例如SignatureCode.driver = driver
。
第二步,单击“确认”按钮以触发方法confirm_sign_code
,在该方法中,我们使用driver = self.driver
来回调类属性中先前保存的driver
。
现在,我们已经成功获得了先前打开的浏览器界面driver
,可以在以后的操作中将其关闭。
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
import selenium
from selenium.webdriver.firefox.options import Options
import time
from selenium.webdriver import ActionChains
from odoo.exceptions import UserError
import os
class SignatureCode(models.TransientModel):
"""
This class is used to receive the captcha when signing
"""
_name = 'signature.code'
_description = 'Signature Code'
driver = None # Define an initialized class property
sign_code = fields.Char('Sign Code')
sign_url = fields.Char('Sign Url')
have_sent = fields.Boolean('Have Sent') # Whether to send an authentication code
manual_sign_id = fields.Many2one('manual.sign',string='Manual Sign')
@api.multi
def send_code(self):
"""
Send a code
:return:
"""
# No interface operation
if self.driver:
try:
self.driver.close()
except:
pass
finally:
SignatureCode.driver = None
options = Options()
options.add_argument('--headless')
# Open the browser, no interface, and don't let selenium generate logs
driver = selenium.webdriver.Firefox(options=options,service_log_path=os.devnull)
# This step is key, once the property has been generated, we need to use the class
# property modification method to save this property to the class for the next call
SignatureCode.driver = driver
self._cr.commit()
driver.get(self.sign_url)
time.sleep(15)
if not self.manual_sign_id.have_got:
first_confirm_button = driver.find_element_by_xpath("/html/body/div/div/div[10]/div/div[3]/span/button/span")
first_confirm_button.click()
self.manual_sign_id.have_got = True
self._cr.commit()
time.sleep(2)
bottom = driver.find_elements_by_xpath("/html/body/div/div/div[2]/div/div[9]/span/img[@class='toBottom']")
if bottom:
bottom[0].click()
time.sleep(3)
ac1 = driver.find_elements_by_class_name("es-drag-seal")[0]
ac2 = driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/div/div[5]/div/div/span")
time.sleep(1)
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
time.sleep(2)
submit_button = driver.find_element_by_xpath("//button//span[text()='submit']")
submit_button.click()
time.sleep(3)
driver.switch_to.frame(0)
short_message = driver.find_element_by_xpath("//a[text()='sign']")
short_message.click()
time.sleep(3)
send_code = driver.find_element_by_xpath("//div[@class='el-form-item__content']//button//span[text()='get code']")
send_code.click()
time.sleep(2)
self.have_sent = True
self._cr.commit()
raise UserError(_('The authentication code has been sent to the phone, please check the receipt'))
@api.multi
def confirm_sign_code(self):
"""
validation code
:return:
"""
if not self.have_sent:
raise UserError(_('Please send the verification code first'))
if not self.sign_code:
raise UserError(_('Please fill sign code'))
sign_code = self.sign_code
# Since we have previously modified class properties with classes, as long as we
# don't close the wizard, the class properties that have been changed will not be
# released.
driver = self.driver
# Enter the verification code
input_code = driver.find_element_by_xpath("//div[@class='el-input']//input[@class='el-input__inner' and @placeholder='Enter the verification code']")
input_code.send_keys(sign_code) # Enter the verification code
time.sleep(2)
# confirm
confirm_button = driver.find_element_by_xpath("//p[@class='realname-form-opt']//button//span[text()='confirm']")
confirm_button.click()
time.sleep(4)
# Here you have to judge whether the captcha is correct or not, based on the web
# domain changes
fail_tip = driver.find_elements_by_xpath("//div[@class='van-toast van-toast--middle van-toast--fail']")
if fail_tip: #failed
fail_msg = driver.find_elements_by_xpath("//div[@class='van-toast__text' and text()='failed']")
if fail_msg:
raise UserError(_('Verification code is incorrect, please re-enter'))
else:
raise UserError(_('Too many verifications, please review again'))
# close
time.sleep(5)
driver.close()
return {
'type':'ir.actions.client',
'tag':'reload'
}
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="signature_code_form_view" model="ir.ui.view">
<field name="name">Signature Code Form View</field>
<field name="model">signature.code</field>
<field name="arch" type="xml">
<form string="Signature Code Form View">
<sheet>
<group>
<group>
<field name="have_sent" invisible="1"/>
<field name="sign_code" readonly="0"/>
</group>
<group>
<button name="send_code" string="Send Code"
attrs="{'invisible':[('have_sent','=',True)]}"
type="object" default_focus="1" class="btn-primary"/>
</group>
</group>
</sheet>
<footer>
<button string="Confirm" name="confirm_sign_code" type="object" default_focus="1"
class="btn-primary"/>
<button string="Cancel" class="btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>