Example #1
0
        def __init__(self, browser: webdriver):
            self._browser = browser

            self.products = []
            self.errors = []

            div_products = self._browser.find_elements_by_xpath(self.locators['divProducts'])
            for div_product in div_products:
                html = etree.parse(StringIO(div_product.get_property('outerHTML')), parser=etree.HTMLParser())

                # Название товара
                name_element = BaseElement(self.locators['txbName'], context=div_product)

                # Цена за единицу продукта
                price_per_product = html.xpath(self.locators['txbPricePerProduct'])[0].text

                # Поле с количеством
                quantity_element = BaseElement(self.locators['inpQuantity'], context=div_product)

                # Итогова цена за товар
                price_amount = convert_price_from_str_to_float(html.xpath(self.locators['txbPriceAmount'])[0].text)
                try:
                    # Итоговая цена без скидки
                    price_amount_old = convert_price_from_str_to_float(
                        html.xpath(self.locators['txbPriceAmountOld'])[0].text)
                except IndexError:
                    price_amount_old = None

                # Элемент удаления товара из корзины
                delete_element = BaseElement(self.locators['btnDelete'], context=div_product)

                # Сообщение о количестве товара в магазине
                try:
                    count_message = html.xpath(self.locators['txbProductCount'])[0].text
                except IndexError:
                    count_message = None

                self.products.append({
                    'name': name_element.text + self._get_params(html),  # название товара
                    'price_per_product': convert_price_from_str_to_float(price_per_product),  # цена за единицу продукта
                    'quantity': int(quantity_element.ge().get_property('value')),  # количество товара
                    'price_amount': price_amount,  # итогова цена за товар
                    'price_amount_old': price_amount_old,  # итоговая цена без скидки
                    'count_message': count_message,  # сообщение о количеством товара в магазине
                    'elements': {
                        'name': name_element,  # элемент название товара
                        'quantity': quantity_element,  # элемент количество товара
                        'delete': delete_element  # элемент удаления товара из корзины
                    }
                })

                self._error_in_quantity(self.products[-1]['name'], quantity_element, count_message)
Example #2
0
        def _error_in_quantity(self, product_name: str, inp_quantity: BaseElement, count_message: str) -> None:
            """ Поле количество указанного товара """

            error = 0

            if "isError__" in inp_quantity.ge().get_attribute('class'):
                error += 1

            if count_message:
                error += 1

            if error == 2:
                self.errors.append(('product_quantity', product_name))
Example #3
0
    def open_item_by_names_in_left_menu(self, menu_item: str,
                                        sub_menu_item: str) -> None:
        """ Открыть раздел сайта по имени раздела и пункта в левом меню """

        menu_item_parent_element = BaseElement(
            self.base_admin_shop_locators['txbMenu'].format(menu_item) + "/..")

        if 'is-open' not in menu_item_parent_element.ge().get_attribute(
                'class'):
            # Если родительская категория не раскрыта, раскрываю
            BaseElement(self.base_admin_shop_locators['txbMenu'].format(
                menu_item)).click()

        # Открываю подменю
        BaseElement(self.base_admin_shop_locators['txbSubMenu'].format(
            sub_menu_item)).click()
Example #4
0
    def _parse_page(self) -> dict:
        """ Распарсить страницу товара """

        elements = {}

        # Определение контекста, для парсинга информации на странице
        div_description = BaseElement(self.locators['locDescription'])
        div_description_html = etree.parse(StringIO(
            div_description.ge().get_property('outerHTML')),
                                           parser=etree.HTMLParser())

        # Название товара
        name = div_description_html.xpath(
            self.locators['txtName'])[0].text.strip()

        # Артикул
        vendor_code = None

        temp = div_description_html.xpath(self.locators['txtVendorCode'])
        if temp[0].text is not None:
            temp = temp[0].text.strip()
            if temp:
                vendor_code = {
                    'text': re.sub(r"\s+", " ", temp),
                    'code': re.search(r":\s*(.*)$", temp).group(1).rstrip()
                }

        # Цена и цена от..
        price = None
        price_from = None

        temp = div_description_html.xpath(self.locators['txtPrice'])
        if temp[0].text is not None:
            if "от" in temp[0].text or (temp[0].getparent().text is not None
                                        and "от" in temp[0].getparent().text):
                price_from = convert_price_from_str_to_float(
                    temp[0].text.replace("\xa0", " "))
            else:
                price = convert_price_from_str_to_float(temp[0].text)

        # Цена со скидкой
        price_discount = None

        temp = div_description_html.xpath(self.locators['txtPriceDiscount'])
        if len(temp):
            temp = temp[0].text
            if temp:
                price_discount = convert_price_from_str_to_float(temp)

        # Параметры
        params = None

        div_params = div_description_html.xpath(self.locators['locParams'])
        if len(div_params):
            params = []

            for div_param in div_params:
                # id параметра
                param_id = int(
                    div_param.xpath(
                        self.locators['locParamId'])[0].attrib['name'])

                # выбранное значнеие
                selected = div_param.xpath(
                    self.locators['txtParamSelected'])[0].text

                # Значения
                values = []

                div_values = div_param.xpath(self.locators['locParamValues'])
                for div_value in div_values:
                    # Проверяем отображение значения параметра
                    try:
                        disabled = True if div_value.attrib[
                            'disabled'] else False
                    except KeyError:
                        disabled = False

                    values.append({
                        'id':
                        int(div_value.attrib['data-value']),  # id значения
                        'name': div_value.text,  # имя значения
                        'disabled': disabled,  # отображается ли он
                    })
                params.append({
                    'id': param_id,  # id параметра
                    'selected': selected,  # выбранное значение
                    'values': values,  # словарь значений
                })

        # Поле с количеством
        quantity = None

        temp = div_description_html.xpath(self.locators['inpQuantity'])
        if len(temp):
            quantity = int(temp[0].attrib['value'])  # количество

            elements['quantity_minus'] = BaseElement(
                self.locators['btnQuantityMinus'])
            elements['quantity'] = BaseElement(self.locators['inpQuantity'])
            elements['quantity_plus'] = BaseElement(
                self.locators['btnQuantityPlus'])

        # Кнопка
        button = None

        temp = div_description_html.xpath(self.locators['btnAdd'] + "/span")
        if len(temp):
            button_text = temp[0].text.strip()

            if "Заказать" in button_text:
                button_type = 'preOrder'
            else:
                button_type = 'addToCard'

            button = {
                'text': button_text,  # текст внутри
                'type': button_type,  # тип
            }

            # Элемент кнопка
            elements['button'] = BaseElement(self.locators['btnAdd'])
        else:
            temp = div_description_html.xpath(self.locators['btnPreOrder'] +
                                              "/span")
            if len(temp):
                button = {
                    'text': temp[0].text.strip(),  # текст внутри
                    'type': 'preOrder',  # тип
                }

                # Элемент кнопка
                elements['button'] = BaseElement(self.locators['btnPreOrder'])

        # Количестве товара
        count = None

        temp = div_description_html.xpath(self.locators['locCount'])
        if len(temp):
            text = temp[0].xpath("string()").strip()
            if text:
                text = re.sub(r"\s+", " ", text)

                count = {
                    'text':
                    text,  # текст сообщения
                    'number':
                    int(
                        div_description_html.xpath(self.locators['locCount'] +
                                                   "/span")[0].text),
                }

        result = {
            'name': name,  # название товара
            'vendor_code': vendor_code,  # артикул
            'price': price,  # цена
            'price_from': price_from,  # цена от..
            'price_discount': price_discount,  # цена со скидкой
            'params': params,  # словарь параметров
            'quantity': quantity,  # количество
            'button': button,  # словарь кнопки
            'count': count,  # словарь количества товара в наличии
            'elements': elements  # словарь элементов
        }

        return result
Example #5
0
    def _get_order(self) -> dict:
        order = {}

        div_order_data = BaseElement(self.locators['locOrderData'])
        html = etree.parse(StringIO(
            div_order_data.ge().get_property('outerHTML')),
                           parser=etree.HTMLParser())
        div_fields = html.xpath(self.locators['locOrderDataFields'])

        temp = div_fields[0].text
        order['number'] = re.search(r"(\d{6})", temp).group(0)

        temp = div_fields[1].text
        order['date'] = re.search(r"Дата:\s*(.*)$", temp).group(1)

        temp = div_fields[2].text
        order['type'] = re.search(r"Тип:\s*(.*)$", temp).group(1)

        order['status'] = div_fields[3].xpath(
            self.locators['btnOrderDataField'])[0].attrib['title']
        order['delivery'] = div_fields[4].xpath(
            self.locators['btnOrderDataField'])[0].attrib['title']
        order['payment'] = div_fields[5].xpath(
            self.locators['btnOrderDataField'])[0].attrib['title']

        order['promocode'] = div_fields[-1].xpath(
            self.locators['btnOrderDataField'])[0].attrib['title']
        if len(order['promocode']) != 3:
            order['promocode'] = re.search(r"^(.*)\s-\s.*$",
                                           order['promocode']).group(1)

        order['form'] = []
        # for div_field in div_fields[6:-1]:
        #     order['form'].append(div_field.xpath(self.locators['inpOrderDataFields'])[0].attrib['value'])

        order['products'] = []
        order_table = BaseElement(self.locators['locOrderTable'])
        html = etree.parse(StringIO(
            order_table.ge().get_property('outerHTML')),
                           parser=etree.HTMLParser())
        tr_elements = html.xpath(".//tr")[:-5]
        for tr_element in tr_elements:
            vendor_code = tr_element.xpath(
                ".//span[@class='vendor-code']")[0].text
            order['products'].append({
                'name':
                tr_element.xpath(".//td[@class='sku']")[0].text + "|" +
                vendor_code,
                'price_per_product':
                convert_price_from_str_to_float(
                    tr_element.xpath(".//td[@class='sku-price']")
                    [0].attrib['value']),
                'quantity':
                int(
                    tr_element.xpath(".//td[@class='sku-quantit']")
                    [0].attrib['value']),
                'price_amount':
                convert_price_from_str_to_float(
                    tr_element.xpath(".//td[@class='total-cost']")[0].text),
            })

        order['delivery_tax'] = convert_price_from_str_to_float(
            html.xpath(self.locators['inpDeliveryTax'])[0].attrib['value'])
        order['discount'] = convert_price_from_str_to_float(
            html.xpath(self.locators['inpDiscount'])[0].attrib['value'])
        order['markup'] = convert_price_from_str_to_float(
            html.xpath(self.locators['inpMarkup'])[0].attrib['value'])
        order['total_amount'] = convert_price_from_str_to_float(
            html.xpath(self.locators['txbTotalAmount'])[0].text)

        return order