Селениум - Python | Поля даты рождения с использованием метки - PullRequest
0 голосов
/ 29 апреля 2020

Я хотел бы создать GENERI C python код, который будет заполнять день, месяц и год в правильном поле.

НО не уверен, как.

В В первом примере мы видим, что у нас есть связь между label и input с помощью параметра for (НО нам нужно взять параметр for из метки и каким-то образом проверить, будет ли он содержать DAY, MONTH и et c ..)

Во втором примере мы видим, что input не имеет идентификаторов с помощью оболочки span. Таким образом, мы можем связать label с span, а затем каким-то образом, используя following::/input[0,1,2] найти ДЕНЬ, МЕСЯЦ и т. Д. c ..

ВОПРОС: это какой-либо возможный способ создать общий код c, который будет работать для первого и второго примеров? ЛЮБЫЕ лучшие практики?

Первый сайт:

<div data-readonly="False">
   <label for="Applicants_0__DateOfBirth">Date of birth</label>
   <div class="rhsForm">
      <input type="text" class="split-date-hidden hasDatepicker" id="dp1587032701992">
      <input class="split-date-day" data-val="true" data-val-number="Please enter a valid date (day)" data-val-range="Please enter a valid date (day)" data-val-range-max="31" data-val-range-min="1" id="Applicants_0__DateOfBirth_Day" maxlength="2" name="Applicants[0].DateOfBirth.Day" placeholder="DD" type="text" value="">
      <span class="field-validation-valid" data-valmsg-for="Applicants[0].DateOfBirth.Day" data-valmsg-replace="true"></span>
      <span class="split-date-separator">&nbsp;</span>
      <input class="split-date-month" data-val="true" data-val-number="Please enter a valid date (month)" data-val-range="Please enter a valid date (month)" data-val-range-max="12" data-val-range-min="1" id="Applicants_0__DateOfBirth_Month" maxlength="2" name="Applicants[0].DateOfBirth.Month" placeholder="MM" type="text" value="">
      <span class="field-validation-valid" data-valmsg-for="Applicants[0].DateOfBirth.Month" data-valmsg-replace="true"></span>
      <span class="split-date-separator">&nbsp;</span>
      <input class="split-date-year" data-val="true" data-val-number="Please enter a valid date (year)" data-val-range="Please enter a valid date (year)" data-val-range-max="5000" data-val-range-min="1000" id="Applicants_0__DateOfBirth_Year" maxlength="4" name="Applicants[0].DateOfBirth.Year" placeholder="YYYY" type="text" value="">
      <span class="field-validation-valid" data-valmsg-for="Applicants[0].DateOfBirth.Year" data-valmsg-replace="true"></span>
      <img class="split-date-calendar-button" src="./Create a case _ the Coventry for intermediaries 3_files/CalendarIcon.png" alt="Show calendar">
      <span class="field-validation-valid" data-valmsg-for="Applicants[0].DateOfBirth" data-valmsg-replace="true"></span>
   </div>
</div>

Второй сайт:

<div class="sel formItemContainer" f-class="EntryRow" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False">
    <div class="emc" id="Entry.Customer.C1.BirthDateEmc" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False"></div>
    <label class="sc" for="Entry.Customer.C1.BirthDate" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False">Date of birth</label>
    <div class="si" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False">
      <span f-class="PatternEntry" f-iscustom="True" f-valuetype="Date" f-minimumlength="3" f-validationname="date of birth" f-isrequired="True" f-isrequiredrule="System.True" f-isreadonlyrule="Data.Customers.C1.AuthenticatedOrPersonalDetailsReadOnly" id="Entry.Customer.C1.BirthDate" value="23/02/1990" f-entryname="Customer.C1.BirthDate" f-submitsdata="True" class="date" xmlns:msxsl="urn:schemas-microsoft-com:xslt" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False" f-readonlyruleresult="False">
        <input type="text" f-class="PatternPart" f-iscustom="True" f-behaviours="formItemChanged" value="444" maxlength="2" size="2" f-parttype="substring" f-partstart="1" f-partlength="2" f-isreadonly="False" f-hasreadonlyrulebeenappliedbefore="True" c-originalvalue="23/02/1989">
        <span f-class="PatternPart" f-parttype="static" f-value="/" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False">/</span>
        <input type="text" f-class="PatternPart" f-iscustom="True" f-behaviours="formItemChanged" value="02" maxlength="2" size="2" f-parttype="substring" f-partstart="4" f-partlength="2" f-isreadonly="False" f-hasreadonlyrulebeenappliedbefore="True" c-originalvalue="23/02/1989">
        <span f-class="PatternPart" f-parttype="static" f-value="/" f-hasreadonlyrulebeenappliedbefore="True" f-isreadonly="False">/</span>
        <input type="text" f-class="PatternPart" f-iscustom="True" f-behaviours="formItemChanged" value="1989" maxlength="4" size="4" f-parttype="substring" f-partstart="7" f-partlength="4" f-isreadonly="False" f-hasreadonlyrulebeenappliedbefore="True" c-originalvalue="23/02/1989">
        </span>
    </div>
</div>

Давайте использовать параметры:

d = '01'
m = '02'
y = '1933'

ar = [d,m,y]

Тогда potential код будет:

l = 'Date of birth'
fls = browser.find_elements_by_xpath('//label[contains(.,"{}")]'.format(l))
    if fls:
        # loop through array <<ar>> and pass each value one by one  
        element = browser.find_elements_by_xpath('//*[@id="{}"]'.format(fls[0].get_attribute("for")))

        if element:
            containtInput = element[0].tag_name.lower() == "input"
            if containtInput:
                x = element[0].find_elements_by_xpath(./following::/input[0])
                x.send_keys(value)
                break

1 Ответ

1 голос
/ 29 апреля 2020

Я не думаю, что было бы хорошей идеей тратить слишком много времени на общее решение c, когда решение для страницы c легко, когда оно выполнено хорошо. Если вы уверены, что все страницы, которые вы хотите использовать, используют формат DD / MM / YYYY и все поля имеют номера c, тогда вы можете попробовать что-то вроде этого:

def fill_date(input_holder_div, data):
    fields = input_holder_div.find_elements_by_xpath('./input[@type="text"]')
    for i in range(3):
        fields[-i-1].clear()
        fields[-i-1].send_keys(data[-i-1])

my_date = [11, 11, 1980]
# fill_date(driver.find_element_by_xpath('//*[@f-class="EntryRow"]'), my_date)
# fill_date(driver.find_element_by_xpath('//*[@class="rhsForm"]'), my_date)

Вызов функции с правильный родитель и данные, и работа сделана. Часть -i-1 требуется для заполнения только 3 последних полей ввода и игнорирования скрытого поля ввода, если такой элемент присутствует. Но есть побочные эффекты.

Что если на странице нет родительского элемента, который содержит только эти 3 поля ввода текста. Что если вы столкнетесь со страницей с форматом даты ГГГГ / ММ / ДД или месяцами, выбранными по имени ...

Если вы хотите выполнить очень похожий или одинаковый рабочий процесс в двух разных макетах, тогда вам, вероятно, стоит проверить подход объекта страницы . Концепция заключается в том, что вы определяете в классе, как делать вещи на странице, а затем просто вызываете методы, и они делают то, что хотели.

Пример:

class BasePage:

    def __init__(self, driver):
        self.driver = driver

    @staticmethod
    def _fill(input_element, data):
        input_element.clear()
        input_element.send_keys(data)


class FirstPage(BasePage):

    def fill_day(self, data):
        field = self.driver.find_element_by_xpath('//*[@class="split-date-day"]')
        self._fill(field, data)


class SecondPage(BasePage):

    def fill_day(self, data):
        field = self.driver.find_element_by_xpath('//*[@id="Entry.Customer.C1.BirthDate"]/input')
        self._fill(field, data)

У вас есть Классы FirstPage и SecondPage, которые знают, как делать вещи, например, как заполнять поле ввода дня. Если вы завершите эти два класса (и добавите методы fill_month и fill_year), вы сможете обрабатывать заполнение дат одним и тем же логикой c:

def fill_date(page, data):
    page.fill_day(data[0])
    page.fill_month(data[1])
    page.fill_year(data[2])


first_page = FirstPage(driver)
second_page = SecondPage(driver)

if first_page_is_loaded:
    fill_date(first_page, my_data)
else:
    fill_date(second_page, my_data)

Если рабочий процесс страниц очень похож все, что вам нужно сделать, это использовать правильный объект страницы. Вы можете справиться с незначительными различиями, переместив некоторые логи c в объект страницы и используя тот же поток в основной логи c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...