Commit 8841d1b8 authored by 17322369953's avatar 17322369953
Browse files

去掉多余的框架

parent 9dd0cd47
"""
日志生成步骤:
1,设置存放日志的目录,不存在则创建。
2,设置日志的级别’DE_BUG‘,’INFO‘,’WARING‘,’ERROR‘,CRITICAL’.
3,设置写入日志的格式‘[%(asctime)s][%(threadName)s][line:%(lineno)d] %(levelname)s: %(message)s’
4,设置控制台输出
5,设置日志文件名
6,确保每日生成不同的日志文件,且能够区分生成时间,可用logging.handlers.TimeRotatingFileHandler进行处理,使用之前先进行导入
7,将日志对象添加到logger里
8,进行调用即可get_logger(name="test")
9,日期文件全部进去根目录的autotest_sc_log目录下,将日志文件与项目分离,后续可以使用filebet进行日志采集,进入日志云查询日志
"""
import logging
import os
import time
from logging.handlers import TimedRotatingFileHandler
class Log(object):
def __init__(self):
# 获取日志器
self.logger = logging.getLogger()
# 先设置日志的的基础显示等级
self.logger.setLevel(logging.INFO)
# 设置日志的格式‘[%(asctime)s][%(threadName)s][line:%(lineno)d] %(levelname)s: %(message)s’
formatter = '[%(asctime)s] [%(threadName)s] [line:%(lineno)d] %(levelname)s: %(message)s'
log_formatter = logging.Formatter(formatter)
# 设置存放日志的目录,不存在则创建。
# 日志文件将放入根目录下,后续更新日志不影响各个项目。
# 日志目录名叫autotest_sc_log
root_dir = os.path.abspath(os.sep)
# 日志目录
log_dir = os.path.join(root_dir, 'autotest_sc_log')
# 若该目录不存在则创建该目录
if not os.path.exists(log_dir):
os.mkdir(log_dir)
# 设置日志文件名
log_file_name = time.strftime('%Y-%m-%d', time.localtime(time.time())) + '.log'
'''
实例化TimedRotatingFileHandler
filename:日志文件名。
when:日志文件按什么切分。'S'-秒;'M'-分钟;'H'-小时;'D'-天;'W'-周
这里需要注意,如果选择D-天,那么这个不是严格意义上的‘天’,是从你项目启动开始,过了24小时,才会重新创建一个新的日志文件,如果
项目重启,这个时间就会重置。选择‘MIDNIGHT’是指过了凌晨12点就会创建新的日志。
interval:时间间隔
backupCount:是保留日志的个数。默认是0,不会自动删除,如何超过这个数就会自动删除
'''
# 创建文件日志与控制台日志处理器
file_handler = TimedRotatingFileHandler(filename=os.path.join(log_dir, log_file_name),
when='MIDNIGHT',
interval=1,
backupCount=3,
encoding='utf-8')
console_handler = logging.StreamHandler()
# 设置文件日志与控制台日志格式
file_handler.setFormatter(log_formatter)
console_handler.setFormatter(log_formatter)
# 设置文件日志与控制台日志基础等级
# 设置日志的级别’DE_BUG‘,’INFO‘,’WARING‘,’ERROR‘,CRITICAL’.
file_handler.setLevel(logging.INFO)
console_handler.setLevel(logging.INFO)
# 添加日志处理器,文件日志与控制台日志
self.logger.addHandler(file_handler)
self.logger.addHandler(console_handler)
# 实例化,后面直接引入使用
log = Log().logger
import configparser
from config.config import Config
class ReadConfig(object):
def __init__(self):
# 获取ini配置文件解析器
self.config = configparser.RawConfigParser()
# 获取ini配置文件路径
self.ini_path = Config().ini_path
# 读取ini配置文件
self.config.read(self.ini_path, encoding='utf-8')
"""通过section与option获取ini文件的值"""
def get(self, section, option):
return self.config.get(section, option)
"""将段下面的数据项更新"""
def set(self, section, option, value):
self.config.set(section, option, value)
with open(self.ini_path, 'w') as w:
self.config.write(w)
# author:qinguanglei
# ddate:2023/11/14 16:14
# 该功能为读取yaml数据功能
import yaml
import os
def read_yaml(yaml_path):
'''读取yaml文件内容
参数path: 相对路径,起始路径:项目的根目录
realPath: 文件的真实路径,绝对路径地址 '''
if not os.path.isfile(yaml_path):
raise FileNotFoundError("文件路径不存在,请检查路径是否正确:%s" % yaml_path)
# open方法打开直接读出来
f = open(yaml_path, 'r', encoding='utf-8')
cfg = f.read() # 读取出来是yaml文件格式
d = yaml.load(cfg, Loader=yaml.FullLoader) # 因此我们用load方法转字典
print("读取的测试文件数据:%s" % d)
return d
def get_value_by_filed_from_yaml(yaml_path, field):
dictionary = read_yaml(yaml_path)
return dictionary[field]
import os
from email.message import EmailMessage
from common.logger import log
import smtplib
import ssl
import zipfile
from common.read_config import ReadConfig
from datetime import datetime
import time
class Mail(object):
def __init__(self):
# 邮箱服务器
self.mail_host = 'smtp.qq.com'
# 邮件发送者x1
self.mail_sender = '381713747@qq.com'
# 发送者授权码
self.mail_authorization = 'insqahzqxxacbjhd'
# 邮件接受者
self.mail_receivers = 'qinguanglei@sinopharm.com'
def send(self):
context = ssl.create_default_context()
# 发送的信息实例
message = EmailMessage()
# 邮件主题
subject = '自动化测试结果,自动发送,请勿回复。'
message['subject'] = subject
# 邮件发送者
message['From'] = self.mail_sender
# 邮件接受者
message['To'] = self.mail_receivers
# 邮件内容
message.set_content("邮件内容")
try:
# 获取一个smtp对象
smtp_obj = smtplib.SMTP_SSL(self.mail_host, 465, context=context)
smtp_obj.login(self.mail_sender, self.mail_authorization)
smtp_obj.send_message(message)
smtp_obj.quit()
log.info('邮件发送成功')
except smtplib.SMTPException as e:
log.error('邮件发送失败%s' % e)
def zip_dir(self):
# 获取当前日期时间
current_time = time.strftime('%Y-%m-%d_%H:%M:%S', time.localtime(time.time()))
# 获取压缩文件主名字,直接未压缩文件目录
zip_main_name = ReadConfig().get('REPORT-FILE', 'REPORT_DIR')
# 拼接压缩文件名字
zip_name = ''.join([zip_main_name, current_time, '.zip'])
log.info(zip_name)
zip_obj = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED)
for root, dir_names, file_names in os.walk(zip_main_name):
fpath = root.replace(zip_main_name, '')
for file_name in file_names:
zip_obj.write(os.path.join(zip_name, file_name), os.path.join(fpath, file_name))
zip_obj.close()
log.debug('压缩成功')
from pytesseract import image_to_string
from PIL import Image, ImageEnhance
from common.read_config import ReadConfig
from guke.common.logger import log
def gen_text_from_picture():
log.info('开始解析验证码')
# 打开图片,将图片转换为obj
image = Image.open(ReadConfig().config.get('SCREENSHOT', 'ELEMENT_SCREENSHOT_PATH'))
# 识别图中的文字
verify_code_text = image_to_string(image)
# 针对平台,去掉最后一个字符“\n”,不同的平台最后一个字符可能不一样
verify_code_text_no_wrap = verify_code_text.replace('\n', '')
log.info("当前验证码的文字为:" + verify_code_text_no_wrap)
# 使用完成后关闭
image.close()
# 返回验证码
return verify_code_text_no_wrap
def gen_text_from_picture_guke():
log.info('开始解析验证码')
# 打开图片,将图片转换为obj
image = Image.open(ReadConfig().config.get('SCREENSHOT', 'ELEMENT_SCREENSHOT_PATH'))
# 图片2直化
image = image.convert('L')
# 灰度化处理
image = ImageEnhance.Contrast(image)
image = image.enhance(3)
image2 = Image.new('RGB', (150, 60), (255, 255, 255))
image2.paste(image.copy(), (25, 10))
# 识别图中的文字
verify_code_text = image_to_string(image2)
# 针对平台,去掉最后一个字符“\n”,不同的平台最后一个字符可能不一样
verify_code_text_no_wrap = verify_code_text.replace('\n', '')
log.info("当前验证码的文字为:" + verify_code_text_no_wrap)
# 使用完成后关闭
image.close()
# 返回验证码
return verify_code_text_no_wrap
class VerifyCode(object):
def __init__(self, web_element, driver):
self.web_element = web_element
self.driver = driver
def indentify_verify_image(self):
# 先刷新验证码
self.web_element.click()
# 在首页展开后,对整个页面进行截图,截图保存目录在ini配置文件中定义
page_shot_dir = ReadConfig().get('SCREENSHOT', 'PAGE_SCREENSHOT_PATH')
# 截图
self.driver.save_screenshot(page_shot_dir)
# 转换图片为Image对象
page_shot_obj = Image.open(page_shot_dir)
# 获取验证码元素图片的位置
location = self.web_element.location
log.debug("验证码元素图片位置:%s" % location)
# 获取验证码元素图片的大小
size = self.web_element.size
log.debug("验证码元素图片大小:%s" % size)
# 获取图片的四个坐标点
left = location['x']
bottom = location['y']
right = left + size['width']
top = bottom + size['height']
log.debug("图片的四个位置。左:%s右:%s上:%s下:%s" % (left, right, top, bottom))
# 开始按照位置截图
crop_image_obj = page_shot_obj.crop((left, bottom, right, top))
# 将切割好的图片保存,保存的目录为crop_dir,截图保存目录在ini配置文件中定义
crop_dir = ReadConfig().get('SCREENSHOT', 'ELEMENT_SCREENSHOT_PATH')
crop_image_obj.save(crop_dir)
# 识别验证码中的字符
verify_code_text = gen_text_from_picture()
log.debug("当前验证码的文字为:%s" % verify_code_text)
return verify_code_text
def indentify_verify_image_guke(self):
# 先刷新验证码
self.web_element.click()
# 在首页展开后,对整个页面进行截图,截图保存目录在ini配置文件中定义
page_shot_dir = ReadConfig().get('SCREENSHOT', 'PAGE_SCREENSHOT_PATH')
# 截图
self.driver.save_screenshot(page_shot_dir)
# 转换图片为Image对象
page_shot_obj = Image.open(page_shot_dir)
# 获取验证码元素图片的位置
location = self.web_element.location
log.debug("验证码元素图片位置:%s" % location)
# 获取验证码元素图片的大小
size = self.web_element.size
log.debug("验证码元素图片大小:%s" % size)
# 获取图片的四个坐标点
left = location['x']
bottom = location['y']
right = left + size['width']
top = bottom + size['height']
log.debug("图片的四个位置。左:%s右:%s上:%s下:%s" % (left, right, top, bottom))
# 开始按照位置截图
crop_image_obj = page_shot_obj.crop((left, bottom, right, top))
# 将切割好的图片保存,保存的目录为crop_dir,截图保存目录在ini配置文件中定义
crop_dir = ReadConfig().get('SCREENSHOT', 'ELEMENT_SCREENSHOT_PATH')
crop_image_obj.save(crop_dir)
# 识别验证码中的字符
verify_code_text = gen_text_from_picture_guke()
log.debug("当前验证码的文字为:%s" % verify_code_text)
return verify_code_text
# author:qinguanglei
# ddate:2023/3/9 20:46
[HOST]
#URL = http://10.17.65.216:8088/portal/
URL = http://gk.cmic.com.cn/portal/
[ACCOUNT-PURCHASE]
ACCOUNT = admin
PASSWORD = Gyxc1234
[SCREENSHOT]
PAGE_SCREENSHOT_PATH = d:/rf/image/org.png
ELEMENT_SCREENSHOT_PATH = d:/rf/image/curr.png
[LOG-FILE]
LOGFILE_DIR = log
[REPORT-FILE]
REPORT_DIR = report
\ No newline at end of file
import os
class Config(object):
# 项目的目录,现获取本文件的绝对路径,再获取文件目录,再获取上一级目录,就是本项目目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
"""获取ini配置文件的路径"""
@property
def ini_path(self):
# 先拼接ini文件目录
ini_path = os.path.join(self.BASE_DIR, 'config', 'config.ini')
if not os.path.exists(ini_path):
raise FileNotFoundError("配置文件%s不存在!" % ini_path)
return ini_path
# author:qinguanglei
# ddate:2023/11/10 16:25
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.remote.webdriver import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from time import sleep
from datetime import datetime
from common.logger import log
import os
class BasePage(object):
def __init__(self, driver):
# 获取驱动
self.driver = driver
# 线程等待时间,秒
self.time_seconds = 1
def open_page(self, url):
"""打开页面"""
# 获取页面链接
self.driver.get(url)
# 设置隐式等待时间
self.driver.implicitly_wait(10)
# 窗口最大化
self.driver.maximize_window()
'''单击一个元素'''
def single_click(self, page_element):
page_element.click()
def single_click_then_wait(self, page_element, seconds):
page_element.click()
self.wait_seconds(seconds)
'''获取一个元素上的文本信息'''
def get_text(self, page_element):
text = page_element.get_attribute('textContent')
return text
'''填入文本'''
def input_text(self, page_element, text):
page_element.clear()
page_element.send_keys(text)
"""在一定时间内定位到某个元素,且这个元素已经能呈现出来"""
def get_element_wait_presence(self, locator):
self.wait_seconds(self.time_seconds)
element = WebDriverWait(self.driver, 10, 0.1).until(EC.presence_of_element_located(locator))
return element
def refresh_page(self):
"""刷新页面"""
self.driver.refresh()
def move_to_element(self, page_element):
"""移动鼠标仅限于鼠标触发型元素,需要等待元素程序才移动"""
self.wait_seconds(2 * self.time_seconds)
"""鼠标移到page_element上"""
action_chains = ActionChains(self.driver)
action_chains.move_to_element(page_element).perform()
"""切换到iframe上"""
def switch_to_iframe(self, page_element_iframe):
self.wait_seconds(self.time_seconds)
self.driver.switch_to.frame(page_element_iframe)
"""获取一个表的行信息"""
def get_all_rows_from_tale(self, table_element):
self.wait_seconds(self.time_seconds)
rows = table_element.find_elements(By.TAG_NAME, "tr")
return rows
"""获取一个表,指定行的列信息"""
def get_all_columns_from_row(self, row_element):
columns = row_element.find_elements(By.TAG_NAME, "td")
return columns
'''给定一个表中的某行的某列,要输入信息,需要取出该栏位中的input元素-后续看要不要将该方法移出基础库,移到对应的功能库'''
def get_input_from_column(self, column):
element = column.find_element(By.TAG_NAME, 'input')
return element
def wait_seconds(self, seconds):
"""睡眠时间-秒"""
sleep(seconds)
def get_screenshot(self, filename="截图"):
""""截图"""
# 截图根目录
screenshot_dir = './screenshot'
if not os.path.exists(screenshot_dir):
# 目录不存在则创建目录
os.mkdir(screenshot_dir)
# 当前日期
now_date = datetime.now().strftime('%Y%m%d')
# 设置文件目录下按照日期新建的子文件夹
screenshot_date_dir = os.path.join(screenshot_dir, str(now_date))
if not os.path.exists(screenshot_date_dir):
# 不存在则创建
os.mkdir(screenshot_date_dir)
# 时间戳到毫秒级
now_time_ms = datetime.now().strftime('%H%M%S%f')
# 拼接截图的图片名与类型,时间戳 + 文件名 + .png
filename = now_time_ms + filename + ".png"
# 图片目录确定
filepath = os.path.join(screenshot_date_dir, filename)
# 截图保存到该目录
self.driver.get_screenshot_as_file(filepath)
'''展示窗口句柄信息,测试用,只下日志'''
def display_window_handle(self):
log.info('当前窗口的title:%s' % self.driver.title)
log.info('当前窗口的url:%s' % self.driver.current_url)
log.info('当前窗口的句柄:%s' % self.driver.current_window_handle)
log.info('所有句柄:%s' % self.driver.window_handles)
'''获取当前页面title'''
def get_window_title(self):
""""切换页面需要时间"""
self.wait_seconds(self.time_seconds)
return self.driver.title
"""关闭当前页面"""
def close_browser(self):
self.driver.close()
"""关闭所有页面"""
def quit_browser(self):
self.driver.quit()
# author:qinguanglei
# ddate:2023/11/10 16:09
from page_class.base_page import BasePage
from selenium.webdriver.common.by import By
class PageLogin(BasePage):
# 账号
_account_locator = (By.ID, 'input1')
# 密码
_pass_locator = (By.ID, 'input2')
# 验证码输入
_verify_code_locator = (By.ID, 'photoCode')
# 验证码图片
_verify_image_locator = (By.ID, 'canvas')
# 登录按钮
_login_button_locator = (By.ID, 'loginBtn')
# 输入信息后,登录结果,主要针对错误输入
_login_result_locator = (By.XPATH, '//div[@id="simplealert"]/div[@class = "msg"]')
'''获取账号'''
def get_account(self):
return self.get_element_wait_presence(self._account_locator)
'''获取密码'''
def get_password(self):
return self.get_element_wait_presence(self._pass_locator)
'''获取验证码'''
def get_verify_code(self):
return self.get_element_wait_presence(self._verify_code_locator)
'''获取验证码图片元素'''
def get_verify_image(self):
return self.get_element_wait_presence(self._verify_image_locator)
'''获取登录按钮元素'''
def get_login_button(self):
return self.get_element_wait_presence(self._login_button_locator)
'''输入用户密码验证码后,登录结果提示'''
def get_login_result(self):
return self.get_element_wait_presence(self._login_result_locator)
import allure
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from common.read_config import ReadConfig
from test_login.page_login import PageLogin
from common.verifycode import VerifyCode
from common import constant
from common.logger import log
@allure.feature('登录模块')
class TestLogin(object):
@pytest.fixture(scope='function', autouse=True)
def housework(self, browser):
# 驱动器从fixture传来
self.driver = browser
# 执行案例前统一获取页面元素操作方法
self.page_login = PageLogin(self.driver)
# 从配置文件中获取url
self.url = ReadConfig().get('HOST', 'URL')
self.page_login.open_page(self.url)
"""登录成功案例"""
@allure.story('登录成功案例-点击登录')
def test_login_success_click(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 密码
password_element = self.page_login.get_password()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page_login.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page_login.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 判断登录是否成功,登录成功会切换到另外一个页面,通过页面title来判断是否切换成功
assert self.page_login.get_window_title() == constant.LOGIN_SUCCESS
'''验证码错误案例'''
@allure.story('登录验证码错误案例')
def test_login_verify_code_error(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 密码
password_element = self.page_login.get_password()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 获取验证码
# 输入错误的验证码
error_code = '1234'
self.page_login.input_text(verify_input_element, error_code)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert self.page_login.get_text(login_result_element) == constant.VERIFY_CODE_ERROR
'''验证码错误案例'''
@allure.story('不输入用户名报错案例')
def test_login_no_input_userid(self):
# 密码
password_element = self.page_login.get_password()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入密码,密码从配置文件中来
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page_login.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page_login.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert self.page_login.get_text(login_result_element) == constant.NO_USER_OR_PASSWORD
@allure.story('不输入密码报错案例')
def test_login_no_input_password(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page_login.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page_login.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert self.page_login.get_text(login_result_element) == constant.NO_USER_OR_PASSWORD
@allure.story('不输入验证码案例')
def test_login_no_input_verifycode(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 密码
password_element = self.page_login.get_password()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert self.page_login.get_text(login_result_element) == constant.NO_VERIFY_CODE
@allure.story('用户名错误案例')
def test_login_userid_error(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 密码
password_element = self.page_login.get_password()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT') + "ERRORTEST")
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page_login.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page_login.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert self.page_login.get_text(login_result_element) == constant.USER_PASSWORD_ERROR
'''密码错误案例'''
@allure.story('密码错误案例')
def test_login_password_error(self):
# 获取账号输入元素
account_element = self.page_login.get_account()
# 密码
password_element = self.page_login.get_password()
# 验证码
verify_input_element = self.page_login.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page_login.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page_login.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD') + "ERRORTEST")
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page_login.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page_login.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page_login.get_login_button()
# 点击登录
self.page_login.single_click(login_button_element)
# 获取登录结果
login_result_element = self.page_login.get_login_result()
# 断言案例是否执行成功
assert constant.USER_PASSWORD_ERROR in self.page_login.get_text(login_result_element)
# pytest -s test_purchase_management/test_new_purchase_op.py::TestNewPurchase::test_new_purchase --alluredir ./report --clean-alluredir
# pytest -s test_purchase_management/test_new_purchase_op.py::TestNewPurchase::test_new_purchase --count=2
# “00122国药集团四川省医疗器械有限公司”向“1018063 成都安进科技有限公司”;采购“10022230 玻璃火罐222";
# 商品从仓库“103303北京公司-顺义库”出库到仓库“122466 四川骨科分仓”入库。
import pytest
import allure
import time
from selenium import webdriver
from selenium.common import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from common.read_config import ReadConfig
from common.verifycode import VerifyCode
from common.logger import log
from common import constant
from test_purchase_management.page_purchase_op import PagePurchaseOP
@allure.feature("采购测试")
class TestNewPurchase:
'''每执行一个案例都进行登录与退出'''
@pytest.fixture(scope='function', autouse=True)
def house_work(self, browser):
# 驱动器从fixture传来
self.driver = browser
# 从配置文件中获取url
self.url = ReadConfig().get('HOST', 'URL')
# 引入本页面的操作元素
self.page = PagePurchaseOP(self.driver)
# 打开页面
self.page.open_page(self.url)
# 登录
self.login_process()
def login_process(self):
account_element = self.page.get_account()
# 密码
password_element = self.page.get_password()
# 验证码
verify_input_element = self.page.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 登录时,最多尝试5次,5次失败,该案例失败
i = 5
while i > 0:
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page.get_login_button()
# 点击登录
self.page.single_click(login_button_element)
# 判断登录是否成功,登录成功会切换到另外一个页面,通过页面title来判断是否切换成功
if self.page.get_window_title() != constant.LOGIN_SUCCESS:
# 表示不登录成功,此时将1减去1
i -= 1
else:
# 表示登录成功,跳出循环
log.info('登录成功,开始执行案例')
break
if i <= 0:
log.info('本案例执行时登录失败')
assert False
@pytest.mark.start
def test_new_purchase(self):
# 睡眠时间
sleep_time = 2
# 入库公司
enter_company = '00103'
# 供应商
supplier_content = '1003207'
# 协议合同内容
protocol_content = ''
# 商品名字
product_name = '测试商品HCL-0721'
# 商品编码
product_code = '10155572'
# 商品信息
merchandise_content = '10005528'
# 订购数量
purchase_sum = 10
# 仓库模糊搜索内容
ware_content = '103356'
# 业务员内容
businessman_content = ""
# 仓库编码内容
ware_name = '自管库-总库'
# 开始
# 登录完成,开始下单
# 定位采购管理元素
purchase_management_button = self.page.get_purchase_management()
# 鼠标移动到采购管理按钮
self.page.move_to_element(purchase_management_button)
# 定位到隐藏的采购按钮
purchase_button = self.page.get_purchase()
# 鼠标移动到采购按钮
self.page.move_to_element(purchase_button)
# 定位到采购申请op
purchase_op_button = self.page.get_purchase_op()
# 鼠标移动到采购申请op
self.page.move_to_element(purchase_op_button)
# 点击采购申请op
purchase_op_button.click()
# 后续所有操作在采购iframe下先进入到采购iframe
iframe_purchase = self.page.get_iframe_purchase()
# 转到这个iframe下
self.page.switch_to_iframe(iframe_purchase)
# 点击新建
new_create_button = self.page.get_new()
self.page.single_click(new_create_button)
# 后续操作在一对话框形式的iframe里,切换到这个子iframe
sub_iframe_dialog = self.page.get_sub_iframe_dialog()
self.page.switch_to_iframe(sub_iframe_dialog)
# 获取查询公司请求元素
company_request = self.page.get_company_request()
# 点击请求进入查询
self.page.single_click(company_request)
# 获取对话框中的搜索输入条件
company_input = self.page.get_company_input()
# 输入公司编码
self.page.input_text(company_input, enter_company)
# 公司信息输入后,点击搜索
company_search = self.page.get_company_search()
self.page.single_click(company_search)
# 查询后表信息处理,数据详情记录在公司表里,公司表在公司dialog中,先去这个dialog
# 获取公司dialog
company_dialog = self.page.get_company_dialog()
# 从dialog中获取表信息
company_table = self.page.get_table_from_dialog(company_dialog)
# company_table = self.page.get_company_table()
# 在获取该表的行信息
company_table_rows = self.page.get_all_rows_from_tale(company_table)
# 遍历该表所有的行
for i, curr_row in enumerate(company_table_rows):
# 获取当前行的列
columns = self.page.get_all_columns_from_row(curr_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出的公司信息表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,公司编码与输入编码一样的公司信息,因为前端是模糊查询,有可能是公司编码,有可能是公司名称,匹配第一条即可
if (enter_company in self.page.get_text(columns[2])) or (enter_company in self.page.get_text(columns[1])):
'''选中当前的行'''
self.page.single_click(curr_row)
'''点击确认'''
company_table_ensure = self.page.get_company_table_ensure()
self.page.single_click(company_table_ensure)
'''选中后退出,不再查询'''
break
# try:
# # 处理清空提示信息
# clear_mind_element = driver.find_element(By.XPATH, '/html/body/div[41]/div/div/div[3]/button[2]')
# clear_mind_element.click()
# except NoSuchElementException:
# pass
# 切换到仓库信息
ware_info = self.page.get_ware_info()
self.page.single_click(ware_info)
# 点击仓库请求按钮
ware_request = self.page.get_ware_request()
self.page.single_click(ware_request)
# 输入仓库数据
ware_input = self.page.get_ware_input()
self.page.input_text(ware_input, ware_content)
# 搜索仓库信息
ware_search = self.page.get_ware_search()
self.page.single_click(ware_search)
# 仓库dialog
ware_dialog = self.page.get_ware_dialog()
# 确定仓库信息的表
ware_table = self.page.get_ware_table()
# 获取该表下的行数据集
ware_table_rows = self.page.get_all_rows_from_tale(ware_table)
log.info("仓库表的行:%s" % ware_table_rows)
# 遍历仓库表行
for i, current_row in enumerate(ware_table_rows):
# 获取当前行的列
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出仓库表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,因为前端是模糊查询,有可能是仓库编码,有可能是仓库名称,匹配第一条即可
if (ware_content in self.page.get_text(columns[1])) or (ware_content in self.page.get_text(columns[2])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
# ware_table_ensure = self.page.get_ware_table_ensure()
ware_table_ensure = self.page.get_ensure_from_dialog(ware_dialog)
self.page.single_click(ware_table_ensure)
'''选中后退出,不再查询'''
break
# 获取供应商
# 触发请求供应商按钮
supplier_request = self.page.get_supplier_request()
self.page.single_click(supplier_request)
# 输入供应商信息
supplier_input = self.page.get_supplier_input()
self.page.input_text(supplier_input, supplier_content)
# 开始查询,点击搜索按钮查询
supplier_search = self.page.get_supplier_search()
self.page.single_click(supplier_search)
# 获取供应商dialog
supplier_dialog = self.page.get_supplier_dialog()
# 获取查询结果,先获取结果表
supplier_table = self.page.get_table_from_dialog(supplier_dialog)
# 获取供应商表中的所有行
supplier_table_rows = self.page.get_all_rows_from_tale(supplier_table)
# 遍历供应商
for i, current_row in enumerate(supplier_table_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出供应商表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,因为前端是模糊查询,有可能是供应商编码,有可能是供应商名称,匹配第一条即可
if (supplier_content in self.page.get_text(columns[1])) or (
supplier_content in self.page.get_text(columns[2])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
supplier_table_ensure = self.page.get_ensure_from_dialog(supplier_dialog)
self.page.single_click(supplier_table_ensure)
'''选中后退出,不再查询'''
break
# 客户协议
# 客户协议请求按钮
protocol_request = self.page.get_protocol_request()
self.page.single_click(protocol_request)
# 输入协议内容
protocol_input = self.page.get_protocol_input()
self.page.input_text(protocol_input, protocol_content)
# 开始搜索协议
protocol_search = self.page.get_protocol_search()
self.page.single_click(protocol_search)
# 获取协议dialog
protocol_dialog = self.page.get_protocol_dialog()
# 获取协议表
protocol_table = self.page.get_table_from_dialog(protocol_dialog)
# 获取这个表中的行
protocol_table_rows = self.page.get_all_rows_from_tale(protocol_table)
# 遍历行
for i, curr_row in enumerate(protocol_table_rows):
# 获取当前协议的所有列
columns = self.page.get_all_columns_from_row(curr_row)
#for j, curr_column in enumerate(columns):
# 遍历列内容,这里只是先打印出日志,便于查看问题
# log.info('查询出合同协议表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选一列,模糊搜索,匹配合同/协议号,合同号,项目编码,项目名称,业态编码,对方编码,产品线编码
if ((protocol_content in self.page.get_text(columns[1])) or
(protocol_content in self.page.get_text(columns[2])) or
(protocol_content in self.page.get_text(columns[3])) or
(protocol_content in self.page.get_text(columns[4])) or
(protocol_content in self.page.get_text(columns[5])) or
(protocol_content in self.page.get_text(columns[6])) or
(protocol_content in self.page.get_text(columns[8]))):
# 选中当前行
self.page.single_click(curr_row)
# 获取协议确定按钮,点击确定
protocol_ensure = self.page.get_ensure_from_dialog(protocol_dialog)
self.page.single_click(protocol_ensure)
break
# 填写业务员
# 获取业务员请求按钮,点击请求业务员信息
businessman_request = self.page.get_businessman_request()
self.page.single_click(businessman_request)
# 输入业务员信息
businessman_input = self.page.get_businessman_input()
self.page.input_text(businessman_input, businessman_content)
# 点击搜索业务员信息
businessman_search = self.page.get_businessman_search()
self.page.single_click(businessman_search)
# 获取业务员dialog
businessman_dialog = self.page.get_businessman_dialog()
# 获取表信息
businessman_table = self.page.get_table_from_dialog(businessman_dialog)
# 获取表信息里面的当前行
businessman_rows = self.page.get_all_rows_from_tale(businessman_table)
# 遍历业务员
for i, current_row in enumerate(businessman_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出业务员表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,模糊查询,匹配业务员编码,业务员名称,部门编码,部门名称,保证业务类型是‘IS’
if ((businessman_content in self.page.get_text(columns[1])) or
(businessman_content in self.page.get_text(columns[2])) or
(businessman_content in self.page.get_text(columns[3])) or
(businessman_content in self.page.get_text(columns[4]))) and ('IS' == self.page.get_text(columns[5])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
ensure = self.page.get_ensure_from_dialog(businessman_dialog)
self.page.single_click(ensure)
'''选中后退出,不再查询'''
break
# 商品录入
# 点击商品录入按钮
merchandise = self.page.get_merchandise()
self.page.single_click(merchandise)
# 获取商品dialog
merchandise_dialog = self.page.get_merchandise_dialog()
# 输入商品信息
#merchandise_input = self.page.get_input_from_dialog(merchandise_dialog)
merchandise_input = self.page.get_merchandise_input()
self.page.input_text(merchandise_input, merchandise_content)
# 点击搜索
#merchandise_search = self.page.get_search_from_dialog(merchandise_dialog)
merchandise_search = self.page.get_merchandise_search()
self.page.single_click(merchandise_search)
# 获取搜索出来的表信息
merchandise_table = self.page.get_table_from_dialog(merchandise_dialog)
# 获取表的全部行
merchandise_table_rows = self.page.get_all_rows_from_tale(merchandise_table)
# 遍历行
for i, current_row in enumerate(merchandise_table_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出商品表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,模糊查询,匹配商品编码,商品名称,规格型号,厂家物料编码
if ((merchandise_content in self.page.get_text(columns[2])) or
(businessman_content in self.page.get_text(columns[3])) or
(businessman_content in self.page.get_text(columns[4])) or
(businessman_content in self.page.get_text(columns[6]))):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
ensure = self.page.get_ensure_from_dialog(merchandise_dialog)
self.page.single_click(ensure)
'''选中后退出,不再查询'''
break
# 保存
save_button = self.page.get_save()
self.page.single_click(save_button)
# 获取采购单号
order_no = self.page.get_order_no()
log.info("订单号:%s" % self.page.get_text(order_no))
from test_login.page_login import PageLogin
from selenium.webdriver.remote.webdriver import By
class PagePurchaseOP(PageLogin):
# 采购管理元素
_purchase_management_locator = (By.XPATH, '//div[@class="menuNavItem" and @sysname="采购管理"]')
# 采购元素
_purchase_locator = (By.XPATH, '//div[@class="sec-menu" and @navname="采购"]')
# 采退元素
_return_locator = (By.XPATH, '//div[@class="sec-menu" and @navname="采退"]')
# 采购订单op
_purchase_op_locator = (By.XPATH, '//div[@class="third-menu" and @navname="采购订单(OP)"]')
# 采购iframe
_iframe_purchase_locator = (
By.XPATH, '//iframe[@class="metro-main-frame" and contains(@src,"purchases")]')
# 新建按钮
_new_locator = (By.XPATH, '//span[text() = "新建"]')
# 对话框iframe,填写订单信息需要
_sub_iframe_dialog_locator = (By.XPATH, '//iframe[contains(@name,"dialog-iframe")]')
# 请求查询公司信息按钮元素
_company_request_locator = (By.XPATH, '//input[starts-with(@id,"el-id-") and contains(@id,"-106")]/../span/span/i')
# 公司信息输入元素
_company_input_locator = (By.XPATH, '//input[@placeholder = "模糊检索:公司名称,公司编码"]')
# 公司信息搜索元素
_company_search_locator = (By.XPATH, '//input[@placeholder = "模糊检索:公司名称,公司编码"]/../span/span/i')
# 公司表dialog body
_company_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-21") and @class="el-dialog__body"]')
# 公司表-----这个只能找绝对路径了,开发太狠了
# _company_table_locator = (
# By.XPATH, '/html/body/div[6]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
_company_table_locator = (By.CLASS_NAME, "el-table__body")
# 公司确定按钮
_company_table_ensure_locator = (By.XPATH, '//span[@class="ensureBtn"]/button/span[text() = "确定"]')
# 仓库信息
_ware_info_locator = (By.ID, 'tab-a58f571e-7488-4c22-bec0-67428972871d')
# 主体信息
_main_info_locator = (By.ID, 'tab-7667cf55-c391-4f2c-a5ba-c0f6d27b6d3a')
# 请求查询仓库元素
_ware_request_locator = (By.XPATH, '//input[starts-with(@id,"el-id-") and contains(@id,"-107")]/../span/span/i')
# 仓库输入元素
_ware_input_locator = (By.XPATH, '//input[@placeholder = "模糊检索:仓库名称,仓库编码"]')
# 仓库搜索元素
_ware_search_locator = (By.XPATH, '//input[@placeholder = "模糊检索:仓库名称,仓库编码"]/../span/span/i')
# 仓库表-----这个只能找绝对路径了,开发太狠了
# _ware_table_locator = (
# By.XPATH, '/html/body/div[8]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
# 仓库表,通过dialog定位
# _ware_table_locator = (By.XPATH, '//div[@role = "dialog" and @aria-label = "选择仓库"]/*/table[@class = "el-table__body"]')
_ware_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-26") and @class="el-dialog__body"]')
_ware_table_locator = 'By.XPATH, "//table[@class = "el-table__body""'
# 仓库表确认元素---这中确定看着可以统一
_ware_table_ensure_locator = (By.XPATH, '//span[@class="ensureBtn"]/button/span[text() = "确定"]')
# 查询供应商请求元素
_supplier_request_locator = (By.XPATH, '//input[starts-with(@id,"el-id-") and contains(@id,"-108")]/../span/span/i')
# 供应商输入信息
_supplier_input_locator = (By.XPATH, '//input[@placeholder = "模糊检索:供应商名称,供应商编码"]')
# 供应商搜索元素
_supplier_search_locator = (By.XPATH, '//input[@placeholder = "模糊检索:供应商名称,供应商编码"]/../span/span/i')
# 供应商表元素-----这个只能找绝对路径了,开发太狠了
_supplier_table_locator = (
By.XPATH, '/html/body/div[10]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
# 供应商dialog
_supplier_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-31") and @class="el-dialog__body"]')
# 供应商表确定元素---这中确定看着可以统一
_supplier_table_ensure_locator = (By.XPATH, './span[@class="ensureBtn"]/button/span[text() = "确定"]')
_dialog_ensure_locator = './*/span[@class="ensureBtn"]/button/span[text() = "确定"]'
# 协议请求元素
_protocol_request_locator = (By.XPATH, '//input[starts-with(@id,"el-id-") and contains(@id,"-109")]/../span/span/i')
# 协议输入元素
_protocol_input_locator = (By.XPATH,
'//input[@placeholder = "模糊检索:合同/协议号,合同号,项目编码,项目名称,业态编码,对方编码,产品线编码"]')
# 协议搜索元素
_protocol_search_locator = (By.XPATH,
'//input[@placeholder = "模糊检索:合同/协议号,合同号,项目编码,项目名称,业态编码,对方编码,产品线编码"]/../span/span/i')
# 协议dialog元素
_protocol_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-36") and @class="el-dialog__body"]')
# 业务员请求元素
_businessman_request_locator = (
By.XPATH, '//input[starts-with(@id,"el-id-") and contains(@id,"-110")]/../span/span/i')
# 业务员输入元素
_businessman_input_locator = (By.XPATH, '//input[@placeholder="模糊检索:业务员编码,业务员名称,部门编码,部门名称"]')
# 业务员搜索元素
_businessman_search_locator = (
By.XPATH, '//input[@placeholder="模糊检索:业务员编码,业务员名称,部门编码,部门名称"]/../span/span/i')
# 业务员dialog元素
_businessman_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-41") and @class="el-dialog__body"]')
# 商品录入按钮
_merchandise_locator = (By.XPATH, '//span[text()="商品录入"]')
# 商品dialog
_merchandise_dialog_locator = (
By.XPATH, '//div[starts-with(@id,"el-id-") and contains(@id,"-124") and @class="el-dialog__body"]')
# 商品输入元素
_merchandise_input_locator = (By.XPATH, '//input[@placeholder="模糊检索:商品编码,商品名称,规格型号,厂家物料编码"]')
# 商品搜索元素
_merchandise_search_locator = (
By.XPATH, '//input[@placeholder="模糊检索:商品编码,商品名称,规格型号,厂家物料编码"]/../span/span/i')
# dialog中的输入元素
_dialog_input_locator = './*/input[@class="el-input__inner" and @placeholder="模糊检索:商品编码,商品名称,规格型号,厂家物料编码"]'
# dialog中的搜索元素
_dialog_search_locator = './*/span[@class="el-input__prefix-inner"]/i'
"""表格中输入元素"""
_input_in_table_locator = 'input'
# 保存按钮
# _save_locator = (By.XPATH, '//*[@id="process-toolbar"]/button[4]/span/text()')
_save_locator = (By.XPATH, '//*[@id="process-toolbar"]/*/span[text()="保存"]')
# 订单号
_order_no_locator = (By.XPATH, '//*[@id="0b83dfe6-67bc-46bf-b271-5e768a59e415"]/div/div[2]/span')
# 商品明细表
_detail_table = (
By.XPATH, '//*[@id="a55ef0dd-0262-4caa-b701-684a33007ac5"]/div/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/table')
# _detail_table = (
# By.XPATH, '//*[@id="a55ef0dd-0262-4caa-b701-684a33007ac5"]/*/table[@class="vxe-table--body"]')
'''获取采购管理元素'''
def get_purchase_management(self):
return self.get_element_wait_presence(self._purchase_management_locator)
'''获取采购元素'''
def get_purchase(self):
return self.get_element_wait_presence(self._purchase_locator)
'''获取采退元素'''
def get_return(self):
return self.get_element_wait_presence(self._return_locator)
'''获取采购订单op元素'''
def get_purchase_op(self):
return self.get_element_wait_presence(self._purchase_op_locator)
'''获取采购iframe元素'''
def get_iframe_purchase(self):
return self.get_element_wait_presence(self._iframe_purchase_locator)
'''获取新建按钮元素'''
def get_new(self):
return self.get_element_wait_presence(self._new_locator)
'''获取对话框iframe元素'''
def get_sub_iframe_dialog(self):
return self.get_element_wait_presence(self._sub_iframe_dialog_locator)
'''获取查询公司请求按钮'''
def get_company_request(self):
return self.get_element_wait_presence(self._company_request_locator)
'''获取公司输入信息元素'''
def get_company_input(self):
return self.get_element_wait_presence(self._company_input_locator)
'''获取公司搜索按钮元素'''
def get_company_search(self):
return self.get_element_wait_presence(self._company_search_locator)
'''获取公司表元素'''
def get_company_table(self):
# return self.get_element_wait_presence(self._company_table_locator)
# 首先获取公司dialog
company_dialog = self.get_company_dialog()
'''再从公司dialog中获取公司表'''
return self.get_table_from_dialog(company_dialog)
'''获取公司表确定按钮'''
def get_company_table_ensure(self):
return self.get_element_wait_presence(self._company_table_ensure_locator)
'''获取仓库信息'''
def get_ware_info(self):
return self.get_element_wait_presence(self._ware_info_locator)
'''获取主体信息'''
def get_main_info(self):
return self.get_element_wait_presence(self._main_info_locator)
'''获取请求查询仓库元素'''
def get_ware_request(self):
return self.get_element_wait_presence(self._ware_request_locator)
'''获取仓库输入元素'''
def get_ware_input(self):
return self.get_element_wait_presence(self._ware_input_locator)
'''获取仓库搜索元素'''
def get_ware_search(self):
return self.get_element_wait_presence(self._ware_search_locator)
'''获取仓库dialog'''
def get_ware_dialog(self):
return self.get_element_wait_presence(self._ware_dialog_locator)
'''获取仓库表元素'''
def get_ware_table(self):
ware_dialog = self.get_ware_dialog()
return self.get_table_from_dialog(ware_dialog)
'''获取仓库表确定按钮'''
def get_ware_table_ensure(self):
ware_dialog = self.get_ware_dialog()
return ware_dialog.find_element(By.XPATH, '//span[@class="ensureBtn"]/button/span[text() = "确定"]')
# return self.get_child(ware_dialog, self._ware_table_ensure_locator)
'''获取供应商dialog元素'''
def get_supplier_dialog(self):
return self.get_element_wait_presence(self._supplier_dialog_locator)
'''从dialog中获取输入元素'''
def get_input_from_dialog(self, dialog_element):
result = dialog_element.find_element(By.XPATH, self._dialog_input_locator)
self.wait_seconds(self.time_seconds)
return result
'''从dialog中获取搜索元素'''
def get_search_from_dialog(self, dialog_element):
search = dialog_element.find_element(By.XPATH, self._dialog_search_locator)
self.wait_seconds(self.time_seconds)
return search
'''从dialog中获取表信息'''
def get_table_from_dialog(self, dialog_element):
tables = dialog_element.find_elements(By.TAG_NAME, "table")
self.wait_seconds(self.time_seconds)
return tables[1]
'''从dialog中获取确定按钮'''
def get_ensure_from_dialog(self, dialog_element):
ensure = dialog_element.find_element(By.XPATH, self._dialog_ensure_locator)
return ensure
"""从表格中的一个栏位中获取输入元素"""
def get_input_from_table_field(self, field):
element = field.find_element(By.XPATH, self._input_in_table_locator)
return element
'''获取供应商请求元素'''
def get_supplier_request(self):
return self.get_element_wait_presence(self._supplier_request_locator)
'''获取供应商输入元素'''
def get_supplier_input(self):
return self.get_element_wait_presence(self._supplier_input_locator)
'''获取供应商搜索元素'''
def get_supplier_search(self):
return self.get_element_wait_presence(self._supplier_search_locator)
'''获取供应商表元素'''
def get_supplier_table(self):
return self.get_element_wait_presence(self._supplier_table_locator)
'''获取供应商表确定元素'''
def get_supplier_table_ensure(self):
return self.get_element_wait_presence(self._supplier_table_ensure_locator)
'''获取公司dialog'''
def get_company_dialog(self):
return self.get_element_wait_presence(self._company_dialog_locator)
'''获取协议请求元素'''
def get_protocol_request(self):
return self.get_element_wait_presence(self._protocol_request_locator)
'''获取协议输入元素'''
def get_protocol_input(self):
return self.get_element_wait_presence(self._protocol_input_locator)
'''获取协议搜索元素'''
def get_protocol_search(self):
return self.get_element_wait_presence(self._protocol_search_locator)
'''获取协议dialog'''
def get_protocol_dialog(self):
return self.get_element_wait_presence(self._protocol_dialog_locator)
'''获取业务员请求元素'''
def get_businessman_request(self):
return self.get_element_wait_presence(self._businessman_request_locator)
'''获取业务员输入元素'''
def get_businessman_input(self):
return self.get_element_wait_presence(self._businessman_input_locator)
'''获取业务员搜索元素'''
def get_businessman_search(self):
return self.get_element_wait_presence(self._businessman_search_locator)
'''获取业务员dialog'''
def get_businessman_dialog(self):
return self.get_element_wait_presence(self._businessman_dialog_locator)
'''商品录入按钮'''
def get_merchandise(self):
return self.get_element_wait_presence(self._merchandise_locator)
'''商品dialog按钮'''
def get_merchandise_dialog(self):
return self.get_element_wait_presence(self._merchandise_dialog_locator)
'''商品输入元素'''
def get_merchandise_input(self):
return self.get_element_wait_presence(self._merchandise_input_locator)
'''商品搜索元素'''
def get_merchandise_search(self):
return self.get_element_wait_presence(self._merchandise_search_locator)
'''保存按钮元素'''
def get_save(self):
return self.get_element_wait_presence(self._save_locator)
'''订单号'''
def get_order_no(self):
return self.get_element_wait_presence(self._order_no_locator)
'''商品明细表'''
def get_detail_table(self):
return self.get_element_wait_presence(self._detail_table)
# pytest -s test_purchase_management/test_new_purchase_op.py::TestNewPurchase::test_new_purchase --alluredir ./report --clean-alluredir
# pytest -s test_purchase_management/test_new_purchase_op.py::TestNewPurchase::test_new_purchase --count=2
# “00122国药集团四川省医疗器械有限公司”向“1018063 成都安进科技有限公司”;采购“10022230 玻璃火罐222";
# 商品从仓库“103303北京公司-顺义库”出库到仓库“122466 四川骨科分仓”入库。
import pytest
import allure
import time
from selenium import webdriver
from selenium.common import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from common.read_config import ReadConfig
from common.verifycode import VerifyCode
from common.logger import log
from common import constant
from test_purchase_management.page_purchase_op import PagePurchaseOP
@allure.feature("采购测试")
class TestNewPurchase(object):
'''每执行一个案例都进行登录与退出'''
@pytest.fixture(scope='function', autouse=True)
def house_work(self, browser):
# 驱动器从fixture传来
self.driver = browser
# 从配置文件中获取url
self.url = ReadConfig().get('HOST', 'URL')
# 引入本页面的操作元素
self.page = PagePurchaseOP(self.driver)
# 打开页面
self.page.open_page(self.url)
# 登录
self.login_process()
def login_process(self):
account_element = self.page.get_account()
# 密码
password_element = self.page.get_password()
# 验证码
verify_input_element = self.page.get_verify_code()
# 输入账号密码,账号密码从配置文件中来
self.page.input_text(account_element, ReadConfig().get('ACCOUNT-PURCHASE', 'ACCOUNT'))
self.page.input_text(password_element, ReadConfig().get('ACCOUNT-PURCHASE', 'PASSWORD'))
# 登录时,最多尝试5次,5次失败,该案例失败
i = 5
while i > 0:
# 获取验证码
# 先获取验证码图片元素
verify_code_element = self.page.get_verify_image()
# 获取验证码中的文字信息
verify_code_text = VerifyCode(verify_code_element, self.driver).indentify_verify_image_guke()
# 填充验证码文字
self.page.input_text(verify_input_element, verify_code_text)
# 获取登录按钮
login_button_element = self.page.get_login_button()
# 点击登录
self.page.single_click(login_button_element)
# 判断登录是否成功,登录成功会切换到另外一个页面,通过页面title来判断是否切换成功
if self.page.get_window_title() != constant.LOGIN_SUCCESS:
# 表示不登录成功,此时将1减去1
i -= 1
else:
# 表示登录成功,跳出循环
log.info('登录成功,开始执行案例')
break
if i <= 0:
log.info('本案例执行时登录失败')
assert False
@pytest.mark.start
def test_new_purchase(self):
# 睡眠时间
sleep_time = 2
# 入库公司
enter_company = '00103'
# 供应商
supplier_content = '1003207'
# 协议合同内容
protocol_content = ''
# 商品名字
product_name = '测试商品HCL-0721'
# 商品编码
product_code = '10155572'
# 商品信息
merchandise_content = '10005528'
# 多个商品信息
merchandises_content = {"10005528": 10, "10184703": 6, "10154042": 9, "10145318": 7, "10175238": 8,
"10155572": 12, "10156326": 11, "10156327": 2, "10156331": 11, "10157133": 1,
"10153359": 8, "10153360": 10, "10153361": 22, "10153362": 8, "10157011": 29,
"10157012": 72, "10157015": 22, "10157014": 32, "10157849": 42, "10157852": 5}
# 订购数量
purchase_sum = 10
# 仓库模糊搜索内容
ware_content = '103356'
# 业务员内容
businessman_content = ""
# 仓库编码内容
ware_name = '自管库-总库'
# 开始
# 登录完成,开始下单
# 定位采购管理元素
purchase_management_button = self.page.get_purchase_management()
# 鼠标移动到采购管理按钮
self.page.move_to_element(purchase_management_button)
# 定位到隐藏的采购按钮
purchase_button = self.page.get_purchase()
# 鼠标移动到采购按钮
self.page.move_to_element(purchase_button)
# 定位到采购申请op
purchase_op_button = self.page.get_purchase_op()
# 鼠标移动到采购申请op
self.page.move_to_element(purchase_op_button)
# 点击采购申请op
purchase_op_button.click()
# 后续所有操作在采购iframe下先进入到采购iframe
iframe_purchase = self.page.get_iframe_purchase()
# 转到这个iframe下
self.page.switch_to_iframe(iframe_purchase)
# 点击新建
new_create_button = self.page.get_new()
self.page.single_click(new_create_button)
# 后续操作在一对话框形式的iframe里,切换到这个子iframe
sub_iframe_dialog = self.page.get_sub_iframe_dialog()
self.page.switch_to_iframe(sub_iframe_dialog)
# 获取查询公司请求元素
company_request = self.page.get_company_request()
# 点击请求进入查询
self.page.single_click(company_request)
# 获取对话框中的搜索输入条件
company_input = self.page.get_company_input()
# 输入公司编码
self.page.input_text(company_input, enter_company)
# 公司信息输入后,点击搜索
company_search = self.page.get_company_search()
self.page.single_click(company_search)
# 查询后表信息处理,数据详情记录在公司表里,公司表在公司dialog中,先去这个dialog
# 获取公司dialog
company_dialog = self.page.get_company_dialog()
# 从dialog中获取表信息
company_table = self.page.get_table_from_dialog(company_dialog)
# company_table = self.page.get_company_table()
# 在获取该表的行信息
company_table_rows = self.page.get_all_rows_from_tale(company_table)
# 遍历该表所有的行
for i, curr_row in enumerate(company_table_rows):
# 获取当前行的列
columns = self.page.get_all_columns_from_row(curr_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
# for j, curr_column in enumerate(columns):
# log.info('查询出的公司信息表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,公司编码与输入编码一样的公司信息,因为前端是模糊查询,有可能是公司编码,有可能是公司名称,匹配第一条即可
if (enter_company in self.page.get_text(columns[2])) or (enter_company in self.page.get_text(columns[1])):
'''选中当前的行'''
self.page.single_click(curr_row)
'''点击确认'''
company_table_ensure = self.page.get_company_table_ensure()
self.page.single_click(company_table_ensure)
'''选中后退出,不再查询'''
break
# try:
# # 处理清空提示信息
# clear_mind_element = driver.find_element(By.XPATH, '/html/body/div[41]/div/div/div[3]/button[2]')
# clear_mind_element.click()
# except NoSuchElementException:
# pass
# 切换到仓库信息
ware_info = self.page.get_ware_info()
self.page.single_click(ware_info)
# 点击仓库请求按钮
ware_request = self.page.get_ware_request()
self.page.single_click(ware_request)
# 输入仓库数据
ware_input = self.page.get_ware_input()
self.page.input_text(ware_input, ware_content)
# 搜索仓库信息
ware_search = self.page.get_ware_search()
self.page.single_click(ware_search)
# 仓库dialog
ware_dialog = self.page.get_ware_dialog()
# 确定仓库信息的表
ware_table = self.page.get_ware_table()
# 获取该表下的行数据集
ware_table_rows = self.page.get_all_rows_from_tale(ware_table)
log.info("仓库表的行:%s" % ware_table_rows)
# 遍历仓库表行
for i, current_row in enumerate(ware_table_rows):
# 获取当前行的列
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
# for j, curr_column in enumerate(columns):
# log.info('查询出仓库表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,因为前端是模糊查询,有可能是仓库编码,有可能是仓库名称,匹配第一条即可
if (ware_content in self.page.get_text(columns[1])) or (ware_content in self.page.get_text(columns[2])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
# ware_table_ensure = self.page.get_ware_table_ensure()
ware_table_ensure = self.page.get_ensure_from_dialog(ware_dialog)
self.page.single_click(ware_table_ensure)
'''选中后退出,不再查询'''
break
# 获取供应商
# 触发请求供应商按钮
supplier_request = self.page.get_supplier_request()
self.page.single_click(supplier_request)
# 输入供应商信息
supplier_input = self.page.get_supplier_input()
self.page.input_text(supplier_input, supplier_content)
# 开始查询,点击搜索按钮查询
supplier_search = self.page.get_supplier_search()
self.page.single_click(supplier_search)
# 获取供应商dialog
supplier_dialog = self.page.get_supplier_dialog()
# 获取查询结果,先获取结果表
supplier_table = self.page.get_table_from_dialog(supplier_dialog)
# 获取供应商表中的所有行
supplier_table_rows = self.page.get_all_rows_from_tale(supplier_table)
# 遍历供应商
for i, current_row in enumerate(supplier_table_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
# for j, curr_column in enumerate(columns):
# log.info('查询出供应商表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,因为前端是模糊查询,有可能是供应商编码,有可能是供应商名称,匹配第一条即可
if (supplier_content in self.page.get_text(columns[1])) or (
supplier_content in self.page.get_text(columns[2])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
supplier_table_ensure = self.page.get_ensure_from_dialog(supplier_dialog)
self.page.single_click(supplier_table_ensure)
'''选中后退出,不再查询'''
break
# 客户协议
# 客户协议请求按钮
protocol_request = self.page.get_protocol_request()
self.page.single_click(protocol_request)
# 输入协议内容
protocol_input = self.page.get_protocol_input()
self.page.input_text(protocol_input, protocol_content)
# 开始搜索协议
protocol_search = self.page.get_protocol_search()
self.page.single_click(protocol_search)
# 获取协议dialog
protocol_dialog = self.page.get_protocol_dialog()
# 获取协议表
protocol_table = self.page.get_table_from_dialog(protocol_dialog)
# 获取这个表中的行
protocol_table_rows = self.page.get_all_rows_from_tale(protocol_table)
# 遍历行
for i, curr_row in enumerate(protocol_table_rows):
# 获取当前协议的所有列
columns = self.page.get_all_columns_from_row(curr_row)
# for j, curr_column in enumerate(columns):
# 遍历列内容,这里只是先打印出日志,便于查看问题
# log.info('查询出合同协议表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选一列,模糊搜索,匹配合同/协议号,合同号,项目编码,项目名称,业态编码,对方编码,产品线编码
if ((protocol_content in self.page.get_text(columns[1])) or
(protocol_content in self.page.get_text(columns[2])) or
(protocol_content in self.page.get_text(columns[3])) or
(protocol_content in self.page.get_text(columns[4])) or
(protocol_content in self.page.get_text(columns[5])) or
(protocol_content in self.page.get_text(columns[6])) or
(protocol_content in self.page.get_text(columns[8]))):
# 选中当前行
self.page.single_click(curr_row)
# 获取协议确定按钮,点击确定
protocol_ensure = self.page.get_ensure_from_dialog(protocol_dialog)
self.page.single_click(protocol_ensure)
break
# 填写业务员
# 获取业务员请求按钮,点击请求业务员信息
businessman_request = self.page.get_businessman_request()
self.page.single_click(businessman_request)
# 输入业务员信息
businessman_input = self.page.get_businessman_input()
self.page.input_text(businessman_input, businessman_content)
# 点击搜索业务员信息
businessman_search = self.page.get_businessman_search()
self.page.single_click(businessman_search)
# 获取业务员dialog
businessman_dialog = self.page.get_businessman_dialog()
# 获取表信息
businessman_table = self.page.get_table_from_dialog(businessman_dialog)
# 获取表信息里面的当前行
businessman_rows = self.page.get_all_rows_from_tale(businessman_table)
# 遍历业务员
for i, current_row in enumerate(businessman_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
# for j, curr_column in enumerate(columns):
# log.info('查询出业务员表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,模糊查询,匹配业务员编码,业务员名称,部门编码,部门名称,保证业务类型是‘IS’
if ((businessman_content in self.page.get_text(columns[1])) or
(businessman_content in self.page.get_text(columns[2])) or
(businessman_content in self.page.get_text(columns[3])) or
(businessman_content in self.page.get_text(columns[4]))) and ('IS' == self.page.get_text(columns[5])):
'''选中当前行'''
self.page.single_click(current_row)
'''点击确认'''
ensure = self.page.get_ensure_from_dialog(businessman_dialog)
self.page.single_click(ensure)
'''选中后退出,不再查询'''
break
# 商品录入
# 点击商品录入按钮
merchandise = self.page.get_merchandise()
self.page.single_click(merchandise)
# 获取商品dialog
merchandise_dialog = self.page.get_merchandise_dialog()
# 获取商品信息输入框
# merchandise_input = self.page.get_input_from_dialog(merchandise_dialog)
merchandise_input = self.page.get_merchandise_input()
# 输入商品信息
for key in merchandises_content.keys():
'''输入当前的商品'''
self.page.input_text(merchandise_input, key)
# 点击搜索
# merchandise_search = self.page.get_search_from_dialog(merchandise_dialog)
merchandise_search = self.page.get_merchandise_search()
self.page.single_click(merchandise_search)
# 获取搜索出来的表信息
merchandise_table = self.page.get_table_from_dialog(merchandise_dialog)
# 获取表的全部行
merchandise_table_rows = self.page.get_all_rows_from_tale(merchandise_table)
# 遍历行
for i, current_row in enumerate(merchandise_table_rows):
# 获取当前供应商的列信息
columns = self.page.get_all_columns_from_row(current_row)
# 遍历列内容,这里只是先打印出日志,便于查看问题
# for j, curr_column in enumerate(columns):
# log.info('查询出商品表,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 挑选出一列,模糊查询,匹配商品编码,商品名称,规格型号,厂家物料编码
if ((merchandise_content in self.page.get_text(columns[2])) or
(businessman_content in self.page.get_text(columns[3])) or
(businessman_content in self.page.get_text(columns[4])) or
(businessman_content in self.page.get_text(columns[6]))):
'''选中当前行'''
self.page.single_click(current_row)
# 选择商品结束后,再确定
'''点击确认'''
ensure = self.page.get_ensure_from_dialog(merchandise_dialog)
self.page.single_click(ensure)
# 再依次填入商品数量
# 获取商品明细表
# 商品明细表这里操作需要等待一会,人工操作也要等,设计就是这样
# 等待的时间为输入商品数量的一半
self.page.wait_seconds(len(merchandises_content))
# detail_table = self.page.get_detail_table()
detail_table = self.driver.find_element(By.XPATH,
'//*[@id="a55ef0dd-0262-4caa-b701-684a33007ac5"]/div/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/table')
# 获取商品明细表中所有行
# detail_table_rows = self.page.get_all_rows_from_tale(detail_table)
detail_table_rows = detail_table.find_elements(By.TAG_NAME, 'tr')
# 遍历商品行,填入商品数量
for i, current_row in enumerate(detail_table_rows):
# 获取当前行所有的列
#columns = self.page.get_all_columns_from_row(current_row)
columns = current_row.find_elements(By.TAG_NAME, 'td')
# 遍历列内容,这里只是先打印出日志,便于查看问题
#for j, curr_column in enumerate(columns):
# log.info('查询出详情清单,的第 %s 行,第 %s 列的内容为 %s' % (i, j, self.page.get_text(curr_column)))
# 取出当前的商品内容,因为是模糊匹配,所以要商品编码,商品名称,规格型号,厂家物料编码
# columns[8]-商品名称,columns[9]-商品编码,columns[10]-厂家物料编码,columns[11]-规格型号
if ((self.page.get_text(columns[8]) in merchandises_content.keys()) or
(self.page.get_text(columns[9]) in merchandises_content.keys()) or
(self.page.get_text(columns[10]) in merchandises_content.keys()) or
(self.page.get_text(columns[11]) in merchandises_content.keys())):
# 获取当前商品的订购数量元素,columns[12]为数量列
# 先点击该元素
#self.page.single_click(columns[12])
columns[12].click()
# 再获取输入元素
#quantity_element = self.page.get_input_from_column(columns[12])
quantity_element = columns[12].find_element(By.TAG_NAME, 'input')
# 填入输入的数量
#self.page.input_text(quantity_element, merchandises_content.get(self.page.get_text(columns[9])))
quantity_element.clear()
quantity_element.send_keys(merchandises_content.get(self.page.get_text(columns[9])))
# 保存
save_button = self.page.get_save()
self.page.single_click(save_button)
# 获取采购单号
order_no = self.page.get_order_no()
log.info("订单号:%s" % self.page.get_text(order_no))
# pytest -s test_purchase_management/test_new_yaohuodan.py::TestNewYaohuodan::test_new_yaohuodan
# “00122国药集团四川省医疗器械有限公司”向“1030573 国药集团北京医疗器械有限公司”;采购“10001249 一次性使用吸引管";
# 商品从仓库“103303北京公司-顺义库”出库到仓库“122301 自管库-波科红海”入库。
# 调货
# 入 国药集团重庆医疗器械有限公司 重庆南区骨科分仓
# 出 国药集团重庆医疗器械有限公司
# 商品 10005528
import pytest
import time
from selenium import webdriver
from selenium.common import NoSuchElementException
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from PIL import Image
from common import verifycode
class TestNewYaohuodan:
@pytest.mark.yaohuodan
def test_new_yaohuodan(self):
# 睡眠时间
sleep_time = 3
# 入库公司
enter_company = '国药集团四川省医疗器械有限公司'
# 出库公司
exit_company = '国药集团北京医疗器械有限公司'
# 商品名字
product_name = '一次性使用吸引管'
# 商品编码
product_code = '10001249'
# 订购数量
purchase_sum = 4
# 仓库编码内容
ware_code_content = 122302
# 仓库编码内容
ware_name = '自管库-波科蓝海'
# 开始
# 获取驱动,谷歌浏览器
driver = webdriver.Chrome("./chromedriver.exe")
# 10秒加载
driver.implicitly_wait(10)
# time_wait失效时间
wait = 5
# 该驱动器的失效时间控制
time_wait = WebDriverWait(driver, wait)
# 打开多采平台,买家
driver.get(url="http://10.17.65.216:8088/portal/")
print("打开骨科主页面成功")
# 页面最大化设置
driver.maximize_window()
# 输入账号
account = driver.find_element(By.ID, 'input1')
account.send_keys("XQZ")
print("账号输入完毕")
# 输入密码
password = driver.find_element(By.ID, 'input2')
password.send_keys("Gyxc1234")
print("输入密码成功")
print('开始处理验证码')
# 首先在页面展开完后,进行全页面截图,截图目录用shot_dir来存储,这个自己定
# 页面全面展开后,再截图,否则会出现截图出问题,这里sleep一段时间
# 指定全页面截图保存的目录
page_shot_dir = "d:/rf/image/org.png"
# 截图
driver.save_screenshot(page_shot_dir)
# 转换图片为Image对象
page_shot_obj = Image.open(page_shot_dir)
# 获取验证码元素
verify_code_element = driver.find_element(By.ID, 'canvas')
print("验证码元素:", verify_code_element)
# 获取验证码元素图片的位置
location = verify_code_element.location
print("验证码元素图片位置:", location)
# 获取验证码元素图片的大小
size = verify_code_element.size
print("验证码元素图片大小:", size)
# 获取图片的四个坐标点
left = location['x']
bottom = location['y']
right = left + size['width']
top = bottom + size['height']
print("图片的四个位置。", "左:", left, "右:", right, "上:", top, "下:", bottom)
# 开始按照位置截图
crop_image_obj = page_shot_obj.crop((left, bottom, right, top))
# 将切割好的图片保存,保存的目录为crop_dir,这个自己定
crop_dir = "d:/rf/image/curr.png"
crop_image_obj.save(crop_dir)
# 识别验证码中的字符
verify_code_text = verifycode.gen_text_from_picture(crop_dir)
print("当前验证码的文字为:", verify_code_text)
# 开始填充验证码
# 获取验证码输入元素
verify_input = driver.find_element(By.ID, 'photoCode')
verify_input.send_keys(verify_code_text)
print("验证码填充完毕")
# 提交
submit_button = driver.find_element(By.ID, 'loginBtn')
submit_button.click()
print("提交完毕")
# 登录完成,开始下单
print("登录完成,开始下单")
# 定位采购管理元素
purchase_management_button = time_wait.until(
ec.visibility_of_element_located((By.XPATH, '/html/body/div[1]/div[4]/div/div/div[4]')))
# 这里有浮动隐藏按钮展示,需要等待一下
# time.sleep(sleep_time)
# 鼠标移动到采购管理按钮
ActionChains(driver).move_to_element(purchase_management_button).perform()
# 定位到隐藏的采购按钮
purchase_button = driver.find_element(By.XPATH, '/html/body/div[1]/div[9]/div[1]')
# 这里有浮动隐藏按钮展示,需要等待一下
time.sleep(sleep_time)
# 鼠标移动到采购按钮
ActionChains(driver).move_to_element(purchase_button).perform()
# 定位到要货申请特一级
apply_level1_button = driver.find_element(By.XPATH, '/html/body/div[1]/div[9]/div[1]/div/div[1]')
# 鼠标移动到要货申请特一级,点击
ActionChains(driver).move_to_element(apply_level1_button).perform()
# 点击要货申请特一级
apply_level1_button.click()
# 获取新建按钮
# 新建按钮在iframe下,先定位到iframe
iframe = driver.find_element(By.XPATH, '//*[@id="awsui-tabs-content"]/div[2]/div/iframe')
print('1111111')
# 转到这个iframe下
driver.switch_to.frame(iframe)
print('11222211111')
# 在这个iframe下定位新建按钮,点击新建
new_create_button = driver.find_element(By.XPATH,
'//*[@id="aws-dw-toolbar-area-div"]/div[1]/div/div[1]/div/div/div[1]/div/div/button')
print('11234534511111')
new_create_button.click()
# 开始填写要货申请单
# 要货申请单在另外一个frame中,为上个frame的子frame,切换到这个子框架
# 从框架切换到子框架,若使用xpath,一定要用绝对路径
sub_iframe = driver.find_element(By.XPATH, '/html/body/div[2]/div/div/div[2]/div/div[2]/div/div/div/iframe')
driver.switch_to.frame(sub_iframe)
print('1122211111111111')
# 定位主体信息中的公司名称
body_company_name = driver.find_element(By.XPATH,
'//*[@id="933e2a09-8c6e-43f3-9637-30cd53ac5e39"]/div/div[2]/div/div/div/div/div/div/div/span/span/i')
print('111111155555555cle')
body_company_name.click()
# 获取对话框中的搜索输入条件
search_input = driver.find_element(By.XPATH,
'/html/body/div[7]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/input')
search_input.send_keys(enter_company)
# 输入搜索条件后,点击搜索
search_action = driver.find_element(By.XPATH,
'/html/body/div[7]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/span/span/i')
search_action.click()
# 表内容刷新一下
time.sleep(sleep_time)
# 查询后表信息处理
# 先获取该表
table_element = driver.find_element(By.XPATH,
'/html/body/div[7]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
# 在获取该表的行数
row_count = table_element.find_elements(By.TAG_NAME, "tr")
print('row_count', len(row_count))
if len(row_count) == 1:
# 获取当前的表行
row_result = driver.find_element(By.XPATH,
'/html/body/div[7]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table/tbody/tr')
# 选择该行
row_result.click()
else:
if len(row_count) > 1:
# 获取当前的表行
row_result = driver.find_element(By.XPATH,
'/html/body/div[7]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table/tbody/tr[1]')
# 选择该行
row_result.click()
# 点击确定
sure_button = driver.find_element(By.XPATH, '/html/body/div[7]/div/div/div/div[2]/span/button[1]')
sure_button.click()
try:
# 处理清空提示信息
clear_mind_element = driver.find_element(By.XPATH, '/html/body/div[40]/div/div/div[3]/button[2]')
clear_mind_element.click()
except NoSuchElementException:
pass
# 填写业务员
# 点击业务员按钮
businessman_element = driver.find_element(By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[2]/div[1]/div/div/div[3]/div[2]/div/div[2]/div/div/div/div/div/div/div/span/span/i')
businessman_element.click()
# 此时会弹框,等下
time.sleep(sleep_time)
# 获取表信息
businessman_table = driver.find_element(By.XPATH,
'/html/body/div[9]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
# 表的行数与列数
businessman_row_count = 0
businessman_column_count = 0
# 获取表信息里面的当前行
businessman_rows = businessman_table.find_elements(By.TAG_NAME, 'tr')
# 获取行数量
businessman_row_count = len(businessman_rows)
# 获取列数量
if businessman_row_count > 0:
businessman_columns = businessman_rows[0].find_elements(By.TAG_NAME, 'td')
businessman_column_count = len(businessman_columns)
print("当前业务人员,行数:", businessman_row_count, "列数:", businessman_column_count)
# 循环遍历行,找出部门类型为is的行
for index, current_row in enumerate(businessman_rows):
# 定位当前的部门类型
department_type = current_row.find_elements(By.TAG_NAME, 'td')[5]
# 当前的部门类型
department_type_text = department_type.text
print("当前部门类型为:", department_type_text)
print("当前行:", index)
if department_type_text == 'IS':
# 选中当前出现is的行
current_row.click()
break
# 选中后,确定
sure_businessman = time_wait.until(
ec.visibility_of_element_located((By.XPATH, '/html/body/div[9]/div/div/div/div[2]/span/button[1]')))
sure_businessman.click()
# 切换到仓库管理
ware_management_element = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[1]/div/div/div/div[3]')))
ware_management_element.click()
# 仓库“122306代管库”入库
# 点击仓库请求按钮
ware_request_button = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[2]/div[2]/div/div/div[1]/div[1]/div/div[2]/div/div/div/div/div/div/div/span/span/i')))
ware_request_button.click()
# 输入仓库编码
ware_code_input = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[13]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/input')))
ware_code_input.send_keys(ware_code_content)
# 搜索返回仓库编码挑选出的内容
ware_response_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[13]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/span/span/i')))
ware_response_button.click()
# 操作选择出来的仓库编码
# 确定仓库信息的表
ware_table = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[13]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')))
# 获取该表下的行数据集
time.sleep(3)
ware_table_rows = ware_table.find_elements(By.TAG_NAME, 'tr')
# 判断表的大小,若为0,表示所选数据为空,结束
if len(ware_table_rows) == 0:
print("仓库编码", ware_code_content, '不存在')
else:
print("仓库编码", ware_code_content, '挑选出来的记录数为:', len(ware_table_rows))
# 选择仓库编码行数据
for index, current_row in enumerate(ware_table_rows):
print('当前仓库编码行', index)
# 获取当前仓库的名称
curr_ware_columns = current_row.find_elements(By.TAG_NAME, 'td')
# 当前行的列数
column_count = len(curr_ware_columns)
print('当前仓库信息的列数:', column_count)
# 展示当前仓库信息
for i, curr_column in enumerate(curr_ware_columns):
print('第', i, '列的值为', curr_column.text)
# 当前仓库名称
curr_ware_name = curr_ware_columns[1].text
print('当前仓库名称:', curr_ware_name)
if curr_ware_name == ware_name:
# 表示找到了需要的仓库名称,选中该仓库
current_row.click()
# 然后确定:
ware_sure_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[13]/div/div/div/div[2]/span/button[1]')))
ware_sure_button.click()
break
# 获取供应商
# 触发请求供应商按钮
supplier_request_button = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[2]/div[2]/div/div/div[1]/div[2]/div/div[2]/div/div/div/div/div/div/div/span/span/i')))
supplier_request_button.click()
# 弹出框,填入需要查询的供应商名
supplier_input = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[15]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/input')))
supplier_input.send_keys(exit_company)
# 开始查询
supplier_inquiry_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[15]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/span/span/i')))
supplier_inquiry_button.click()
# 获取查询结果,先获取结果表
time.sleep(3)
supplier_table = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[15]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')))
# supplier_table = driver.find_element(By.XPATH,
# '/html/body/div[15]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')
supplier_rows = supplier_table.find_elements(By.TAG_NAME, 'tr')
print("根据条件", exit_company, '查询出的供应商名数量为', len(supplier_rows))
# 遍历供应商
for i, curr_supplier_row in enumerate(supplier_rows):
print('当前是第', i, '个供应商')
# 获取当前供应商的列信息
curr_supplier_row_columns = curr_supplier_row.find_elements(By.TAG_NAME, 'td')
print('当前供应商一共有', len(curr_supplier_row_columns), '列')
# 打印列信息
for j, curr_column in enumerate(curr_supplier_row_columns):
print('第', j, '列为', curr_column.text)
# 若供应商名称满足,则挑选
if curr_supplier_row_columns[1].text == exit_company:
# 选中该供应商
curr_supplier_row.click()
# 点击确认
supplier_sure_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[15]/div/div/div/div[2]/span/button[1]')))
supplier_sure_button.click()
break
# 客户协议
# 客户协议请求按钮
protocol_request_button = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[2]/div[2]/div/div/div[2]/div[1]/div/div[2]/div/div/div/div/div/div/div/span/span/i')))
protocol_request_button.click()
time.sleep(3)
# 获取协议表
protocol_table = time_wait.until(ec.visibility_of_element_located(
(By.XPATH,
'/html/body/div[19]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')))
# 获取这个表中的行
protocol_table_rows = protocol_table.find_elements(By.TAG_NAME, 'tr')
print('当前展示协议记录条数:', len(protocol_table_rows))
# 遍历行
for i, protocol_curr_row in enumerate(protocol_table_rows):
print('当前是第', i, '条记录')
# 展开当前协议信息
# 获取当前协议的列
protocol_curr_row_columns = protocol_curr_row.find_elements(By.TAG_NAME, 'td')
print('第', i, '条协议共有', len(protocol_curr_row_columns), '列')
for j, protocol_curr_column in enumerate(protocol_curr_row_columns):
print('第', j, '列的值为', protocol_curr_column.text)
if i == 0: # 简化,选择第一行
protocol_curr_row.click()
protocol_sure_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[19]/div/div/div/div[2]/span/button[1]')))
protocol_sure_button.click()
break
# 商品录入
# 点击商品录入按钮
product_type_button = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[2]/div/div/div[2]/div/div/div[1]/div/div[1]/div/div[1]/div/div/span/div/button[1]')))
product_type_button.click()
# 输入商品信息
# 获取输入商品信息位置
product_input = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[37]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/input')))
product_input.send_keys(product_name)
# 点击按钮开始查询
product_inquire_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[37]/div/div/div/div[1]/div[1]/div[1]/div/div/form/div/div/div/div/span/span/i')))
product_inquire_button.click()
# 开始处理查出的商品信息
time.sleep(3)
# 获取查出的商品表信息
product_table = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[37]/div/div/div/div[1]/div[2]/div[1]/div/div/div/div[1]/div[3]/div/div[1]/div/table')))
# 获取商品表里当前展示的行
product_table_rows = product_table.find_elements(By.TAG_NAME, 'tr')
print('当前根据条件:', product_name, ',搜出的商品记录有', len(product_table_rows), '条')
# 处理具体的记录
for i, product_curr_row in enumerate(product_table_rows):
# 获取当前行的列信息
product_columns = product_curr_row.find_elements(By.TAG_NAME, 'td')
print('当前是第', i, '条记录,本记录的共有', len(product_columns), '列')
# 查看具体的列信息
for j, product_curr_column in enumerate(product_columns):
print('第', j, '列为', product_curr_column.text)
# 商品编码匹配就选择
if product_columns[2].text == product_code:
# 选中当前的商品信息
product_curr_row.click()
# 确认商品
product_sure_button = time_wait.until(ec.visibility_of_element_located(
(By.XPATH, '/html/body/div[37]/div/div/div/div[2]/span/button[1]')))
product_sure_button.click()
break
# 编辑商品详情信息
# 获取详情表
time.sleep(3)
detail_table = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[2]/div/div/div[2]/div/div/div[2]/div[2]/div[1]/div[2]/table')))
# 获取表的行
detail_table_rows = detail_table.find_elements(By.TAG_NAME, 'tr')
print('商品详情一共有', len(detail_table_rows), '条记录')
for i, detail_curr_row in enumerate(detail_table_rows):
# 获取当前行的列信息
detail_curr_columns = detail_curr_row.find_elements(By.TAG_NAME, 'td')
for j, detail_curr_column in enumerate(detail_curr_columns):
print('第', i, ',行第', j, '列的内容为', detail_curr_column.text)
# 填入订购数量
if j == 4:
# 第四列表示订购数量
detail_curr_column.click()
# 从该列元素中获取input元素,专门用来输入数据
input_element = detail_curr_column.find_element(By.TAG_NAME, 'input')
# 输入订购数量
input_element.send_keys(purchase_sum)
time.sleep(sleep_time)
# 保存
save_button = time_wait.until(
ec.visibility_of_element_located((By.XPATH, '/html/body/div[2]/div/div[1]/div[2]/div[2]/div[2]/button[4]')))
save_button.click()
# 切换到主体信息
body_module = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[1]/div/div/div/div[2]')))
body_module.click()
# 获取要货申请单号
time.sleep(3)
apply_no = time_wait.until(ec.visibility_of_element_located((By.XPATH,
'/html/body/div[2]/div/div[2]/div/div[2]/div[2]/div/div[1]/form/div[1]/div/div/div/div[2]/div[1]/div/div/div[1]/div/div/div[2]/span')))
apply_no_text = apply_no.text
print('最终的申请单号为', apply_no_text)
time.sleep(sleep_time)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment