Поскольку OP сказал, что это был AngularJS DatePicker, и я никогда не имел никаких контактов с Угловое, сам не будучи передний конец парень, я хотел бы узнать что-то, и теперь я разделяю его с вами, что бы это ни стоило.
Это тест Geb, который не использует никаких JS, но собирает информацию от Angular datepicker и взаимодействует с ним с помощью Geb или Selenium. Тест показывает, как
- получить выбранную дату из текстового поля Datepicker с помощью
myNavigator.singleElement().getAttribute("value")
(также работает для неактивных элементов управления),
- получить выбранную дату, открыв DatePicker и поиск выделенных дат в календарь (работает только для активных элементов управления, конечно),
- довольно утомительно взаимодействовать с DatePicker, выбрав Xmas день текущего года (декабрь-25) по
- открытия DatePicker,
- нажатия на текущем месяце для того, чтобы открыть месяц селектора года
- щелкающих декабря, фактически закрыв селектор месяца снова
- щелкать на 25-е дня, эффективно снова закрывая DatePicker,
- наконец проверки, является ли правильная дата была установлена путем чтения текстовой метки, как в примере # 1.
Страница:
package de.scrum_master.stackoverflow
import geb.Page
import geb.navigator.Navigator
import java.time.Month
import java.time.format.TextStyle
import static java.util.Calendar.*
class DatePickerPage extends Page {
static url = "https://material.angularjs.org/1.1.2/demo/datepicker"
static at = { heading == "Datepicker" }
static now = new GregorianCalendar()
static content = {
heading { $("h2 > span.md-breadcrumb-page.ng-binding").text() }
datePickerButtons { $("md-datepicker > button") }
datePickerInputFields { $(".md-datepicker-input") }
activeDatePicker(required: false) { $(".md-datepicker-calendar-pane.md-pane-open") }
selectedDate { activeDatePicker.$(".md-calendar-selected-date") }
currentMonthLabel {
activeDatePicker
.$("td.md-calendar-month-label", text: "${getMonthShort(now)} ${now.get(YEAR)}")
}
selectedMonth(required: false) { $("td.md-calendar-selected-date") }
}
String getDatePickerValue(Navigator datePickerInputField) {
datePickerInputField.singleElement().getAttribute("value")
}
Navigator getMonthLabel(Calendar calendar) {
$(".md-calendar-month-label", text: "${calendar.get(YEAR)}").closest("tbody")
.$("span", text: getMonthShort(calendar)).closest("td")
}
Navigator getDayOfMonthLabel(Calendar calendar) {
activeDatePicker
.$(".md-calendar-month-label", text: "${getMonthShort(calendar)} ${calendar.get(YEAR)}")
.closest("tbody")
.$("span", text: "${calendar.get(DAY_OF_MONTH)}")
.closest("td")
}
String getMonthShort(Calendar calendar) {
Month
.of(calendar.get(MONTH) + 1)
.getDisplayName(TextStyle.FULL, new Locale("en"))
.substring(0, 3)
}
}
Тест:
package de.scrum_master.stackoverflow
import geb.module.FormElement
import geb.spock.GebReportingSpec
import spock.lang.Unroll
import static java.util.Calendar.*
class DatePickerIT extends GebReportingSpec {
def now = new GregorianCalendar()
def xmas = new GregorianCalendar(now.get(YEAR), 12 - 1, 25)
@Unroll
def "Get selected date from Angular date label"() {
when: "a date picker on the Angular demo page is chosen"
DatePickerPage page = to DatePickerPage
def datePickerInputField = page.datePickerInputFields[datePickerIndex]
then: "that date picker instance is (in-)active as expected"
datePickerInputField.module(FormElement).enabled == isEnabled
when: "the active date is read from the date picker's text input field"
String activeDateString = page.getDatePickerValue(datePickerInputField)
String todayString = "${now.get(MONTH) + 1}/${now.get(DAY_OF_MONTH)}/${now.get(YEAR)}"
then: "it is today"
todayString == activeDateString
where:
datePickerIndex << [0, 1, 2, 3, 4, 5, 6, 7, 8]
isEnabled << [true, false, true, true, true, true, true, true, true]
}
@Unroll
def "Get selected date from opened Angular date picker"() {
when: "a date picker on the Angular demo page is chosen"
DatePickerPage page = to DatePickerPage
def datePickerButton = page.datePickerButtons[datePickerIndex]
then: "that date picker instance is active (not greyed out)"
datePickerButton.module(FormElement).enabled
when: "the calendar button for the date picker is clicked"
datePickerButton.click()
then: "the date picker pop-up opens, displaying the current month"
waitFor 3, { page.activeDatePicker.displayed }
when: "the active date's timestamp is read from the highlighted day in the calendar"
def selectedDateMillis = page.selectedDate.attr("data-timestamp") as long
def sinceMidnightMillis = now.getTimeInMillis() - selectedDateMillis
then: "it is today"
sinceMidnightMillis >= 0
sinceMidnightMillis < 24 * 60 * 60 * 1000
where:
datePickerIndex << [0, 2, 4, 5, 6, 7, 8]
}
def "Set date in Angular date picker"() {
when: "the first date picker's calendar button on the Angular demo page is clicked"
DatePickerPage page = to DatePickerPage
page.datePickerButtons[0].click()
then: "the date picker pop-up opens, displaying the current month"
waitFor 3, { page.activeDatePicker.displayed }
when: "the current month label is clicked"
page.currentMonthLabel.click()
then: "the month selection page opens"
waitFor 3, { page.selectedMonth.displayed }
page.selectedMonth.text() == page.getMonthShort(now)
when: "December for the current year is selected"
page.getMonthLabel(xmas).click()
then: "the month selection page closes again"
waitFor 3, { !page.selectedMonth.displayed }
when: "Xmas Day (25) is selected on the month calendar"
page.getDayOfMonthLabel(xmas).click()
then: "the date picker pop-up closes again"
waitFor 3, { !page.activeDatePicker.displayed }
when: "the active date is read from the date picker's text input field"
String activeDateString = page.getDatePickerValue(page.datePickerInputFields[0])
String xmasDayString = "${xmas.get(MONTH) + 1}/${xmas.get(DAY_OF_MONTH)}/${xmas.get(YEAR)}"
then: "it is Xmas Day of the current year"
xmasDayString == activeDateString
}
}
Преимущество такого подхода очевидна: Вы только взаимодействовать со страницей в пути пользователя будет/может также делать, тем самым избегая манипулирования страницей способом, недоступным для пользователя (whi ch приведет к плохим испытаниям).
Обновление: Я переработал код в использовании объекта страницы.
Используйте следующий код для решения проблемы: js.exec ("document.getElementsByClassName ('ui-form-control ng-isolate-scope') [0] .removeAttribute ('readonly')") – Amy
Если атрибут только для чтения и вы его изменяете, какой тест это? Вы проверяете то, что пользователь не может сделать на странице. Я думаю, это звучит довольно бессмысленно. Попытайтесь сосредоточиться на тестировании фактического поведения пользователя, а не на взломе страницы. Или вы используете Geb как средство автоматизации браузера и взлома страницы, а не как инструмент тестирования? В этом случае я понимаю вопрос, даже если это не то, для чего был изобретен Геб. – kriegaex
kriegaex, на самом деле я не могу получить элементы (дату, месяц) datepicker (угловой) даже с помощью xpath, поэтому я хочу установить значение для datepicker напрямую. Но похоже, что он принимает только то значение, которое вы нажимаете. Я все еще не нахожу способ установить значение datepicker – Amy