Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 22.52 KB | None | 0 0
  1. import time
  2. import datetime
  3. import importlib
  4. from faker import Faker
  5. from selenium import webdriver
  6. from selenium.webdriver import ActionChains
  7. from selenium.webdriver.common.by import By
  8. from selenium.webdriver.common.keys import Keys
  9. from selenium.webdriver.support.ui import Select
  10. from selenium.webdriver.common.alert import Alert
  11. from selenium.webdriver.support.ui import WebDriverWait
  12. from selenium.webdriver.support import expected_conditions as EC
  13. from selenium.common.exceptions import NoAlertPresentException, \
  14.     ElementNotVisibleException, TimeoutException, ElementNotInteractableException
  15.  
  16. from core import sets
  17. from .sut import SimplifiedUnitTest
  18.  
  19.  
  20. class Base(SimplifiedUnitTest):
  21.  
  22.     WARNING = "div[class='swal2-popup swal2-modal swal2-show']"
  23.  
  24.     def __setup__(self):
  25.         super(Base, self).__setup__()
  26.         chrome_options = webdriver.ChromeOptions()
  27.         chrome_options.add_argument("--disable-infobars")
  28.         chrome_options.add_argument("--headless")
  29.         chrome_options.add_argument("window-size=1920,1080")
  30.         self.driver = webdriver.Chrome(options=chrome_options)
  31.         self.options = None
  32.         self.fake = Faker()
  33.         self.date_today = datetime.datetime.strftime(datetime.datetime.now(), '%d/%m/%y')
  34.  
  35.     def refresh_page(self):
  36.         """
  37.        Open home page
  38.        """
  39.         self.driver.get(self.options.BASE_URL)
  40.         self.wait_till_requests_done_and_document_ready()
  41.  
  42.     def test_login(self):
  43.         """
  44.        Test for login into client
  45.        """
  46.         if self.options is None:
  47.             raise ValueError("Options are not defined")
  48.         self.driver.get(self.options.BASE_URL)
  49.         WebDriverWait(self.driver, 10).until(
  50.             EC.presence_of_element_located((By.NAME, "submit")),
  51.             "Couldn't load main page to log in"
  52.         )
  53.         Select(self.driver.find_element_by_name("db")).select_by_value(
  54.             self.options.DATABASE
  55.         )
  56.         login = self.driver.find_element_by_name("login")
  57.         password = self.driver.find_element_by_name("password")
  58.         login.send_keys(self.options.USER)
  59.         password.send_keys(self.options.PASSWORD)
  60.         password.submit()
  61.         self.wait_till_requests_done_and_document_ready()
  62.         assert not self.is_error()
  63.         return True
  64.  
  65.     def is_error(self):
  66.         """
  67.        Check if Enapps error is present
  68.        """
  69.         errors = self.driver.find_elements_by_class_name('ui-dialog-title')
  70.         if len(errors) > 0 and errors[0].text.strip() == "Enapps":
  71.             return True
  72.         return False
  73.  
  74.     def close_popup(self):
  75.         """
  76.        Close any pop-up
  77.        """
  78.         self.driver.find_element_by_css_selector("button[class*='ui-dialog-titlebar-close']").click()
  79.         self.wait_till_requests_done_and_document_ready()
  80.         return True
  81.  
  82.     def save_and_close_popup(self):
  83.         """
  84.        Click button Save and Close into popup
  85.        """
  86.         self.driver.find_element_by_css_selector("button[class='oe_button oe_formopenpopup-form-save-close']").click()
  87.         self.wait_till_requests_done_and_document_ready()
  88.  
  89.     def save_and_close_second_popup(self):
  90.         """
  91.        Click button Save and Close into second popup
  92.        """
  93.         self.driver.find_element_by_xpath("(//button[@class='oe_button oe_formopenpopup-form-save-close'])[2]").click()
  94.         self.wait_till_requests_done_and_document_ready()
  95.  
  96.     def get_popup(self, name):
  97.         """
  98.        Focus on popup
  99.        """
  100.         spans = self.driver.find_elements_by_class_name("ui-dialog-title")
  101.         for span in spans:
  102.             if span.text == name:
  103.                 break
  104.         return self.driver.find_element_by_css_selector(
  105.             "div[aria-labelledby='{}']".format(span.get_attribute("id"))
  106.         )
  107.  
  108.     def trigger_menu(self, menu_chains):
  109.         """
  110.        Example:
  111.            1. to open Activities: ["CRM", "Activities", "TODO List"]
  112.  
  113.        :param menu_chains: {list} sequence of menu items
  114.        :return: {boolean} True, False
  115.        """
  116.         main_menu = WebDriverWait(self.driver, 3).until(
  117.             EC.presence_of_element_located((By.ID, "oe_header")),
  118.             "Couldn't load main menu"
  119.         )
  120.         for chain in menu_chains:
  121.             WebDriverWait(main_menu, 1).until(
  122.                 EC.presence_of_all_elements_located((By.LINK_TEXT, chain)),
  123.                 "Couldn't find menu item {}".format(chain)
  124.             )[-1].click()
  125.         self.wait_till_requests_done_and_document_ready()
  126.         assert not self.is_error() and not self.is_warning()
  127.  
  128.     def select_view(self, view_type=None):
  129.         """
  130.        Open specified view
  131.  
  132.        :param view_type: {srt} (list/form/kanban/graph/calendar/map/pivot)
  133.        """
  134.         if view_type is None:
  135.             return None
  136.         view = self.driver.find_element_by_css_selector(
  137.             "button[data-view-type='{}']".format(view_type)
  138.         )
  139.         # check if needed view already chosen
  140.         if view.get_attribute("disabled") == "disabled":
  141.             return True
  142.         view.click()
  143.         return self.wait_till_requests_done_and_document_ready()
  144.  
  145.     def select_tab(self, name):
  146.         """
  147.        Go to o2many tab
  148.        """
  149.         self.scroll_page_to_top()
  150.         self.driver.find_element_by_partial_link_text(name).click()
  151.         return True
  152.  
  153.     def close_tab(self, index=0):
  154.         """
  155.        Close tab or tabs
  156.        """
  157.         self.scroll_page_to_top()
  158.         tabs = self.driver.find_elements_by_css_selector(
  159.             "span[class^='close'][class$='icon-remove']"
  160.         )
  161.         if index == -1:
  162.             for tab in tabs:
  163.                 tab.click()
  164.                 self._handle_alert()
  165.         elif tabs:
  166.             tabs[index].click()
  167.             self._handle_alert()
  168.         return True
  169.  
  170.     def press_button_on_form_view(self, name, element=None, block=False, max_time=10):
  171.         """
  172.        Press button by name
  173.        """
  174.         form = element if element else self.driver
  175.         warning = f"Could not find button {name}"
  176.         self.scroll_page_to_top()
  177.         WebDriverWait(form, 1).until(
  178.             EC.presence_of_element_located((By.NAME, name)), warning
  179.         ).click()
  180.         self.wait_till_requests_done_and_document_ready(max_time)
  181.  
  182.     def press_create_button_on_tree_view(self):
  183.         """
  184.        Press button "Create New" on list view
  185.        """
  186.         self.wait_till_requests_done_and_document_ready()
  187.         create_buttons = self.driver.find_elements_by_xpath(
  188.             "//button[@type='button']"
  189.             "[@class='oe_button oe-list-add']"
  190.             "[@original-title='Create New']"
  191.         )
  192.         action = ActionChains(self.driver)
  193.         element = self.driver.find_element_by_xpath("//div[@class='user_content']")
  194.         action.move_to_element(element).perform()
  195.         for button in create_buttons:
  196.             try:
  197.                 button.click()
  198.                 continue
  199.             except (ElementNotVisibleException, ElementNotInteractableException):
  200.                 pass
  201.         self.wait_till_requests_done_and_document_ready()
  202.         msg = "ERROR OR WARNING DETECTED"
  203.         assert not self.is_error() and not self.is_warning(), msg
  204.         return True
  205.  
  206.     def press_button_on_form_header(self, button_name):
  207.         """
  208.        Allowed buttons: save/cancel/new/copy/delete
  209.        """
  210.         button_class_names = {
  211.             "save": "oe_form_button_save",
  212.             "cancel": "oe_form_button_cancel",
  213.             "new": "oe_form_button_create",
  214.             "copy": "oe_form_button_duplicate",
  215.             "delete": "oe_form_button_delete",
  216.         }
  217.         self.scroll_page_to_top()
  218.         self.driver.find_element_by_css_selector(
  219.             "div[class^='oe_form_buttons'][class$='oe_button_group']"
  220.         ).find_element_by_css_selector(
  221.             "button[class*='{}']".format(button_class_names[button_name])
  222.         ).click()
  223.         self._handle_alert()
  224.         self.wait_till_requests_done_and_document_ready()
  225.         assert not self.is_error() and not self.is_warning()
  226.  
  227.     def press_search_button(self, element=None):
  228.         """
  229.        Press button "Search"
  230.        """
  231.         self.scroll_page_to_top()
  232.         driver = element if element else self.driver
  233.         driver.find_element_by_name("search").click()
  234.         self.wait_till_requests_done_and_document_ready()
  235.  
  236.     def _handle_alert(self, action="accept"):
  237.         """
  238.        Allowed actions: [accept/dismiss]
  239.        """
  240.         alert = Alert(self.driver)
  241.         try:
  242.             getattr(alert, action)()
  243.         except NoAlertPresentException:
  244.             pass
  245.         return True
  246.  
  247.     def is_warning(self):
  248.         """
  249.        Check if warning is present
  250.        """
  251.         return bool(
  252.             self.driver.find_elements_by_css_selector(self.WARNING)
  253.         )
  254.  
  255.     def wait_till_requests_done_and_document_ready(self, max_time=15, poll_frequency=1):
  256.         """
  257.        Wait when all web processes will be done
  258.        """
  259.         end_time = time.time() + max_time
  260.         while True:
  261.             WebDriverWait(self.driver, max_time, poll_frequency).until(
  262.                 lambda driver: driver.execute_script(
  263.                     "return document.readyState"
  264.                 ) == "complete",
  265.                 "It takes too long to load page"
  266.             )
  267.             WebDriverWait(self.driver, max_time, poll_frequency).until(
  268.                 lambda driver: driver.execute_script(
  269.                     "return jQuery.active"
  270.                 ) == 0,
  271.                 "It takes too long to load page"
  272.             )
  273.             WebDriverWait(self.driver, max_time).until(
  274.                 EC.invisibility_of_element_located((
  275.                     By.CSS_SELECTOR,
  276.                     "div[class^='blockUI'][class$='blockOverlay']"
  277.                 ))
  278.             )
  279.             if self.driver.execute_script("return jQuery.active") == 0:
  280.                 break
  281.             if time.time() > end_time:
  282.                 raise TimeoutException("Time out")
  283.         return True
  284.  
  285.     def trigger_filters(self, enable=None, disable=None, element=None):
  286.         """
  287.        Work with filters on list view
  288.        """
  289.         element = element if element else self.driver
  290.         if enable is None:
  291.             enable = set()
  292.         if disable is None:
  293.             disable = set()
  294.         search_view = WebDriverWait(element, 1).until(
  295.             EC.presence_of_element_located((By.CLASS_NAME, "search_view")),
  296.             "Couldn't locate search view on form"
  297.         )
  298.         if "all" in disable:
  299.             search_view.find_element_by_name("reset").click()
  300.             disable = set()
  301.         filtered_filters = (f for f in disable if f not in enable)
  302.         # disable filters
  303.         for filter_name in filtered_filters:
  304.             f = element.find_element_by_name(filter_name)
  305.             # skip if filter already disabled
  306.             if f.get_attribute("class") == "filter_label":
  307.                 continue
  308.             f.click()
  309.         # enable filters
  310.         for filter_name in enable:
  311.             f = element.find_element_by_name(filter_name)
  312.             if f.get_attribute("class") == "filter_label enabled":
  313.                 continue
  314.             f.click()
  315.         return self.wait_till_requests_done_and_document_ready()
  316.  
  317.     def fill_in_field(self, name, field_type, value, element=None):
  318.         """
  319.        Fill data into field
  320.        """
  321.         if element:
  322.             form_view = element
  323.         else:
  324.             form_view = self.driver.find_element_by_css_selector(
  325.                 "div[id^='widget'][id$='view_form']"
  326.             )
  327.         if field_type in ("char", "text", "integer", "float", "date"):
  328.             self.wait_till_requests_done_and_document_ready()
  329.             self.clear_field(name, field_type, element=element)
  330.             form_view.find_element_by_name(name).send_keys(value)
  331.         elif field_type == "selection":
  332.             Select(form_view.find_element_by_name(name)).select_by_value(
  333.                 value
  334.             )
  335.         elif field_type == "many2one":
  336.             self.clear_field(name, field_type, element=element)
  337.             field = form_view.find_element_by_name(name)
  338.             field.send_keys(Keys.HOME + Keys.SHIFT + Keys.END + Keys.DELETE)
  339.             field.send_keys(value)
  340.             self.wait_till_requests_done_and_document_ready(3)
  341.             field.send_keys(Keys.ARROW_DOWN + Keys.TAB)
  342.         elif field_type == "boolean":
  343.             checkbox = form_view.find_elements_by_css_selector(
  344.                 "label[for='{}']".format(
  345.                     form_view.find_element_by_name(name).get_attribute("id")
  346.                 )
  347.             )[-1]
  348.             span_class = checkbox.find_element_by_tag_name(
  349.                 "span"
  350.             ).get_attribute("class")
  351.             if value is True and span_class == "boolean_icon icon-ok":
  352.                 checkbox.click()
  353.             elif value is False and span_class == "boolean_icon icon-ok on":
  354.                 checkbox.click()
  355.         return True
  356.  
  357.     def fill_in_fields(self, fields, save=True, element=None):
  358.         """
  359.        Fill data into fields
  360.        """
  361.         for field in fields:
  362.             self.fill_in_field(*field, element=element)
  363.         assert not self.is_error() and not self.is_warning()
  364.         if save:
  365.             self.press_button_on_form_header("save")
  366.             self.wait_till_requests_done_and_document_ready()
  367.             assert not self.is_error() and not self.is_warning()
  368.  
  369.     def fill_in_o2m(self, name, records):
  370.         """
  371.        Fill data into field type=o2many
  372.        """
  373.         o2m = self.driver.find_element_by_name(name)
  374.         create = o2m.find_element_by_css_selector(
  375.             "button[class*='oe-list-add']"
  376.         )
  377.         fake_row = "div[class='form-cont']"
  378.         for record in records:
  379.             create.click()
  380.             self.wait_till_requests_done_and_document_ready()
  381.             time.sleep(0.5)
  382.             WebDriverWait(o2m, 7).until(
  383.                 EC.element_to_be_clickable((By.CSS_SELECTOR, fake_row)),
  384.                 "fake row not found :D"
  385.             )
  386.             self.fill_in_fields(record, save=False, element=o2m)
  387.         return True
  388.  
  389.     def fill_in_header_on_tree_view(self, name, field_type, value, method="by_text"):
  390.         """
  391.        Fill data into field on list view
  392.        """
  393.         search_header = self.driver.find_elements_by_css_selector(
  394.             "tr[class^='oe-listview-header-columns']"
  395.         )[-1]
  396.         if field_type in ("char", "text", "integer", "float"):
  397.             search_header.find_element_by_name(name).send_keys(value)
  398.         elif field_type == "many2one":
  399.             pass
  400.         elif field_type in ["selection", "boolean"]:
  401.             search_header.find_element_by_css_selector(
  402.                 "th[data-id='{}']".format(name)
  403.             ).click()
  404.             select = Select(search_header.find_element_by_name(name))
  405.             if method == "by_text":
  406.                 select.select_by_visible_text(value)
  407.                 select.select_by_visible_text(value)
  408.             else:
  409.                 select.select_by_index(value)
  410.                 select.select_by_index(value)
  411.  
  412.     def read_from_list_view(self, start=0, stop=1, o2m=False):
  413.         """
  414.        Read data from list view
  415.        """
  416.         driver = o2m or self.driver
  417.         content = driver.find_element_by_css_selector(
  418.             "tbody[class*='ui-widget-content']"
  419.         )
  420.         records = []
  421.         for tr in content.find_elements_by_tag_name("tr")[:stop]:
  422.             if not tr.get_attribute("data-id"):
  423.                 continue
  424.             values = {}
  425.             for td in tr.find_elements_by_tag_name("td"):
  426.                 if "oe-field-cell" not in td.get_attribute("class"):
  427.                     continue
  428.                 if "oe_boolean" in td.get_attribute("class"):
  429.                     span = td.find_element_by_tag_name("span")
  430.                     span_class = span.get_attribute("class")
  431.                     if "boolean_icon icon-ok on" in span_class:
  432.                         values[td.get_attribute("data-field")] = True
  433.                     else:
  434.                         values[td.get_attribute("data-field")] = False
  435.                 else:
  436.                     values[td.get_attribute("data-field")] = td.text
  437.             records.append(values)
  438.         return records[start:stop]
  439.  
  440.     def read_from_o2m(self, name, start=0, stop=1):
  441.         """
  442.        Read data from o2many field
  443.        """
  444.         o2m = self.driver.find_element_by_name(name)
  445.         return self.read_from_list_view(start, stop, o2m)
  446.  
  447.     def clear_field(self, name, field_type, element=None):
  448.         """
  449.        Clear data from field
  450.        """
  451.         if element:
  452.             form_view = element
  453.         else:
  454.             form_view = self.driver.find_element_by_css_selector(
  455.                 "div[id^='widget'][id$='view_form']"
  456.             )
  457.         if field_type in ("char", "text", "integer", "float", "date"):
  458.             form_view.find_element_by_name(name).clear()
  459.         elif field_type == "many2one":
  460.             field = form_view.find_element_by_name(name)
  461.             field.send_keys(Keys.SHIFT + Keys.HOME + Keys.DELETE)
  462.         return True
  463.  
  464.     def get_info_from_field(self, name, attribute, element=None):
  465.         """
  466.        Read data from field on form view
  467.        """
  468.         if element:
  469.             form_view = element
  470.         else:
  471.             form_view = self.driver.find_element_by_css_selector(
  472.                 "div[id^='widget'][id$='view_form']"
  473.             )
  474.         if attribute == "editable":
  475.             return form_view.find_element_by_name(name).get_attribute("value")
  476.         return form_view.find_element_by_name(name).text()
  477.  
  478.     def open_record_from_o2many(self, name, index=0):
  479.         """
  480.        Open record from o2name by index
  481.        """
  482.         o2m = self.driver.find_element_by_name(name)
  483.         o2m.find_elements_by_css_selector("button[name='edit']")[index].click()
  484.         self.wait_till_requests_done_and_document_ready()
  485.  
  486.     def press_reload_button(self):
  487.         """
  488.        Press button "Reload" on form view
  489.        """
  490.         self.scroll_page_to_top()
  491.         self.driver.find_element_by_css_selector("button[class='oe_vm_switch_reload']").click()
  492.         self.wait_till_requests_done_and_document_ready()
  493.  
  494.     def select_all_lines_in_o2many(self, name, ):
  495.         """
  496.        Select all records in o2many by button "Select Content"
  497.        """
  498.         self.driver.find_element_by_css_selector(
  499.             "div[name='{}'] button[title='Select Content']".format(name)
  500.         ).click()
  501.  
  502.     def context_menu(self, name):
  503.         """
  504.        Press context menu on record into o2many
  505.        """
  506.         first_line = self.driver.find_element_by_xpath(name)
  507.         actions = ActionChains(self.driver)
  508.         return actions.context_click(first_line).perform()
  509.  
  510.     def get_state(self):
  511.         """
  512.        Get state from view
  513.        """
  514.         return self.driver.find_element_by_css_selector(
  515.             "li[class=oe-arrow-list-selected]").text
  516.  
  517.     def click_button_by_text(self, button_name, block=False):
  518.         """
  519.         Click button by label if button hasn't method
  520.        """
  521.         self.driver.find_element_by_xpath(
  522.             "//*[contains(text(), '')]"
  523.         ).find_element_by_xpath(
  524.             "//*[contains(text(), '{}')]".format(button_name)
  525.         ).click()
  526.         self.wait_till_requests_done_and_document_ready()
  527.  
  528.     def close_warning(self):
  529.         """
  530.        Click on button Ok for 'Warning!'
  531.        """
  532.         self.driver.find_element_by_css_selector("button[class='swal2-confirm swal_warning_red swal2-styled']").click()
  533.         self.wait_till_requests_done_and_document_ready()
  534.  
  535.     def click_search_more(self, name, element=None):
  536.         if element:
  537.             form_view = element
  538.         else:
  539.             form_view = self.driver.find_element_by_css_selector(
  540.                 "div[id^='widget'][id$='view_form']"
  541.             )
  542.         field = form_view.find_element_by_name(name)
  543.         self.wait_till_requests_done_and_document_ready(3)
  544.         field.send_keys(Keys.ARROW_UP)
  545.         time.sleep(0.2)
  546.         field.send_keys(Keys.ARROW_UP)
  547.         time.sleep(0.2)
  548.         field.send_keys(Keys.ARROW_UP + Keys.ENTER)
  549.         self.wait_till_requests_done_and_document_ready()
  550.  
  551.     def press_by_action_right_side_bar(self, button_name):
  552.         """
  553.        Click by button from right side bar
  554.        """
  555.         self.driver.find_element_by_xpath(
  556.             "//*[contains(text(), '')]"
  557.         ).find_element_by_xpath(
  558.             "//div[@name='Actions']//*[contains(text(), '{}')]".format(button_name)
  559.         ).click()
  560.         self.wait_till_requests_done_and_document_ready()
  561.  
  562.     def make_editable_o2many_field(self, field_name, index):
  563.         """
  564.        Click by the line for o2many
  565.        """
  566.         self.driver.find_element_by_xpath(
  567.             "(//td[@data-field='product_id'])"
  568.         ).find_element_by_xpath(
  569.             "(//td[@data-field='{}'])[{}]".format(field_name, index)
  570.         ).click()
  571.         self.wait_till_requests_done_and_document_ready()
  572.  
  573.     def scroll_page_to_top(self):
  574.         """
  575.        Scroll page to top
  576.        """
  577.         self.driver.execute_script("scroll(0, 0);")
  578.         self.wait_till_requests_done_and_document_ready()
  579.  
  580.     def press_button_next(self):
  581.         """
  582.        Press Next button on form header
  583.        """
  584.         self.driver.find_element_by_xpath("(//button[@data-pager-action='next'])[last()]").click()
  585.         self.wait_till_requests_done_and_document_ready()
  586.  
  587.     def click_sidebar(self):
  588.         """
  589.        Open sidebar or close
  590.        """
  591.         self.driver.find_element_by_xpath("//a[@class='toggle-sidebar']").click()
  592.         self.wait_till_requests_done_and_document_ready()
  593.  
  594.     def wait_records_on_tree_view(self):
  595.         """
  596.        Wait when will be visible records on tree view
  597.        """
  598.         self.ret = False
  599.         try:
  600.             WebDriverWait(self.driver, 10).until(
  601.                 EC.element_to_be_clickable((By.XPATH, "(//button[@name='edit'])[last()]")))
  602.         except:
  603.             self.ret = True
  604.         if self.ret ==True:
  605.             try:
  606.                 WebDriverWait(self.driver, 10).until(
  607.                     EC.element_to_be_clickable((By.XPATH, "(//th[@class='oe-record-edit-link'])[last()]")))
  608.             except ElementNotVisibleException:
  609.                 "Error, element not visible"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement