body_page.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. '''
  4. @File : body_page.py
  5. @Time : 2024/11/12 08:14:19
  6. @Author : dulip3ng
  7. @Version : 1.0
  8. @Desc : None
  9. '''
  10. from playwright.sync_api import Page, Error
  11. from pages.base_page import BasePage
  12. from common.field_type import FieldType
  13. class BodyPage(BasePage):
  14. def __init__(self, page:Page, locator):
  15. super().__init__(page)
  16. self.locator = locator
  17. def change_sheet(self, sheet_name:str, order:int=1):
  18. """
  19. 切换单据体页签
  20. :param sheet_name: 页面名称
  21. :param order: 可选参数,存在同名页签时指明第几个,从1开始
  22. :return: None
  23. """
  24. self.page.locator(self.locator.SHEET_ARGS_LOC % (sheet_name, order)).click()
  25. def click_button(self, button_name:str, sub_button_name:str=None):
  26. """
  27. 点击单据体按钮或子按钮
  28. 如:新增行
  29. **用法:**
  30. BodyPage.click_button("新增行")
  31. BodyPage.click_button("新增行", "复制行")
  32. :param button_name: 按钮名称
  33. :param sub_button_name: 可选参数,子按钮名称
  34. :return: None
  35. """
  36. self.page.wait_for_load_state("networkidle")
  37. if not sub_button_name:
  38. self.page.locator(self.locator.BUTTON_ARGS_LOC % button_name).first.click()
  39. else:
  40. self.page.locator(self.locator.BUTTON_ARROW_ARGS_LOC % button_name).first.hover()
  41. self.page.locator(self.locator.SUB_BUTTON_ARGS_LOC % sub_button_name).click()
  42. self._click_blank()
  43. def click_line(self, row:int):
  44. """
  45. 选中单据体行(通过点击行序号)
  46. :param row: 行号,从1开始
  47. :return: None
  48. """
  49. self.page.locator(self.locator.ACTIVATE_FIELD_ARGS_LOC % ("序号", row-1, 1)).click()
  50. def _activate_field(self, row:int, field_name:str, order:int=1):
  51. """
  52. 激活字段,单据体字段未激活状态时统一为span元素,无法识别字段类型,无法针对不同字段类型操作
  53. :param field_name: 字段名
  54. :param row: 行号,从1开始
  55. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  56. :return: None
  57. """
  58. self.page.wait_for_load_state("networkidle")
  59. self.page.locator(self.locator.ACTIVATE_FIELD_ARGS_LOC % (field_name, row-1, order)).click()
  60. def _set_text(self, row:int, field_name:str, value:str, order:int=1):
  61. """
  62. 单据体文本字段赋值
  63. :param field_name: 字段名
  64. :param value: 字段值
  65. :param row: 行号
  66. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  67. :return: None
  68. """
  69. self._activate_field(row, field_name, order)
  70. locator = self.page.locator(self.locator.TEXT_FIELD_ARGS_LOC % (field_name, row-1, order))
  71. locator.clear()
  72. locator.fill(value)
  73. self.click_line(1)
  74. def _set_select(self, row:int, field_name:str, value:str, order:int=1):
  75. """
  76. 单据体下拉列表字段赋值
  77. :param field_name: 字段名
  78. :param value: 选项值
  79. :param row: 行号
  80. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  81. :return: None
  82. """
  83. self.page.locator(self.locator.ACTIVATE_FIELD_ARGS_LOC % (field_name, row-1, order)).click()
  84. self.page.locator(self.locator.SELECT_ITEM_ARGS_LOC % value).click()
  85. self.click_line(1)
  86. def _set_base(self, row:int, field_name:str, value:str, order:int=1):
  87. """
  88. 单据体基础资料类型字段赋值
  89. :param field_name: 字段名
  90. :param value: 字段值
  91. :param row: 行号
  92. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  93. :return: None
  94. """
  95. self._activate_field(row, field_name, order)
  96. locator = self.page.locator(self.locator.BASE_FIELD_ARGS_LOC % (field_name, row-1, order))
  97. locator.click()
  98. locator.clear()
  99. locator.fill(value)
  100. locator.press_sequentially(" ")
  101. locator.press("Backspace")
  102. self.page.locator(self.locator.BASE_ITEM_ARGS_LOC % value).nth(0).click()
  103. self.click_line(1)
  104. def set_value(self, row:int, field_name:str, value:str, order:int=1, field_type:FieldType = None):
  105. """
  106. 单据体字段赋值统一方法,根据给定或自动识别的字段类型调用不同方法完成赋值
  107. **用法:**
  108. BodyPage.set_value("衬衣订单号", "26024021", 1)
  109. :param field_name: 字段名
  110. :param value: 字段值
  111. :param row: 行号
  112. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  113. :param field_type: 可选参数,字段类型,不填时自动识别
  114. :return: None
  115. """
  116. if not field_type:
  117. field_type = self._parse_field(row, field_name, order)
  118. match field_type:
  119. case FieldType.TEXT:
  120. self._set_text(row, field_name, value, order)
  121. case FieldType.SELECT:
  122. self._set_select(row, field_name, value, order)
  123. case FieldType.BASE:
  124. self._set_base(row, field_name, value, order)
  125. def _parse_field(self, row:int, field_name:str, order:int=1):
  126. """
  127. 识别单据体字段类型
  128. :param field_name: 字段名
  129. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  130. :return: 字段类型
  131. """
  132. self._activate_field(row, field_name, order)
  133. data_role = self.page.locator(self.locator.PARSE_FILED_ARGS_LOC % (field_name, row-1, order)).get_attribute("data-role")
  134. self.click_line(1)
  135. match data_role:
  136. case "kdbosf7":
  137. return FieldType.BASE
  138. case "dropdownlist":
  139. return FieldType.SELECT
  140. case "kdtextfield" | "kdnumberfield" | "datepicker" | "kdmultilang" | "datetimepicker":
  141. return FieldType.TEXT
  142. def get_row_count(self):
  143. """
  144. 获取单据体总行数
  145. :return: 行数
  146. """
  147. return self.page.locator(self.locator.ROW_COUNT_LOC).inner_text()
  148. def get_value(self, row:int, field_name:str, order:int=1):
  149. """
  150. 获取单据体字段值,不区分字段类型
  151. :param field_name: 字段名
  152. :param row: 行号
  153. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  154. :return: 字段值
  155. """
  156. return self.page.locator(self.locator.FIELD_VALUE_ARGS_LOC % (field_name, row-1, order)).inner_text()
  157. def set_checked(self, row:int, field_name:str):
  158. """
  159. 勾选单据体复选框
  160. :param field_name: 字段名
  161. :param row: 行号
  162. :return: None
  163. """
  164. self.page.locator(self.locator.CHECKBOX_FIELD_ARGS_LOC % (field_name, row-1)).click()
  165. self.click_line(1)
  166. def set_text_in_body_head(self, field_name:str, value:str):
  167. """
  168. 单据体中单据头形式文本字段赋值
  169. 如:销售订单->物料数据->面料规格
  170. :param field_name: 字段名
  171. :param value: 字段值
  172. :return: None
  173. """
  174. locator = self.page.locator(self.locator.TEXT_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name)
  175. locator.clear()
  176. locator.fill(value)
  177. self._click_blank()
  178. def set_select_in_body_head(self, field_name:str, value:str):
  179. """
  180. 单据体中单据头形式下拉列表字段赋值
  181. 如:销售订单->物料数据->货主类型
  182. :param field_name: 字段名
  183. :param value: 选项值
  184. :return: None
  185. """
  186. self.page.locator(self.locator.SELECT_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name).click()
  187. self.page.locator(self.locator.SELECT_ITEM_ARGS_LOC % value).click()
  188. self._click_blank()
  189. def set_base_in_body_head(self, field_name:str, value:str):
  190. """
  191. 单据体中单据头形式基础资料字段赋值
  192. 如:销售订单->物料数据->面料来源
  193. :param field_name: 字段名
  194. :param value: 选项值
  195. :return: None
  196. """
  197. self.page.locator(self.locator.BASE_FIELD_IN_BODY_HEAD_SPAN_ARGS_LOC % field_name).click()
  198. locator = self.page.locator(self.locator.BASE_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name)
  199. locator.clear()
  200. locator.fill(value)
  201. locator.press_sequentially(" ")
  202. locator.press("Backspace")
  203. self.page.locator(self.locator.BASE_ITEM_ARGS_LOC % value).nth(0).click()
  204. self._click_blank()
  205. def get_text_in_body_head(self, field_name:str, order:int=1):
  206. """
  207. 单据体中单据头形式文本字段取值
  208. 如:销售订单->物料数据->面料规格
  209. :param field_name: 字段名
  210. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  211. :return: 字段值
  212. """
  213. # 字段值可能存在1. input中,2.span或其他元素中,目标元素不是input时input_value()方法报错,捕获并换为inner_text()获取
  214. try:
  215. return self.page.locator(self.locator.TEXT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, field_name, order)).input_value()
  216. except Error:
  217. return self.page.locator(self.locator.TEXT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, field_name, order)).inner_text()
  218. def get_select_in_body_head(self, field_name:str, order:int=1):
  219. """
  220. 单据体中单据头形式下拉列表字段取值
  221. 如:销售订单->物料数据->货主类型
  222. :param field_name: 字段名
  223. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  224. :return: 字段值
  225. """
  226. return self.page.locator(self.locator.SELECT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, order)).inner_text()
  227. def get_base_in_body_head(self, field_name:str, order:int=1):
  228. """
  229. 单据体中单据头形式基础资料字段取值
  230. 如:销售订单->物料数据->面料来源
  231. :param field_name: 字段名
  232. :param order: 可选参数,存在同名字段时指明第几个,从1开始
  233. :return: 字段值
  234. """
  235. return self.page.locator(self.locator.BASE_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, order)).inner_text()