2017-01-18 3 views
2

datepicker의 값을 설정하고 싶습니다. 속성은 '읽기 전용'입니다. 내가 속성을 제거 removeAttr()을 시도했지만이 같은 오류가 발생했습니다 :Geb - Geb에서 속성을 제거하는 방법

겁에 질린 : groovy.lang.MissingMethodException : 방법 없음 서명 : geb.navigator.NonEmptyNavigator.removeAttr()는 인수 유형에 적용 : (자바 .lang.String) values ​​: [readonly]

Geb에서 속성을 제거하려면 어떻게해야합니까?

souce에 코드 :

<input ng-show="!date" class="ui-form-control ng-isolate-scope" name="date" placeholder="StartTime" ui-datepicker-trigger="" selected-date="date" readonly="readonly" type="text"> 

내 GEB 코드 :

$('input', placeholder: 'StartTime').removeAttr('readonly') 

감사 게브가 직접 DOM을 수정하는 것을 허용하지 않는 모든

+0

다음 코드를 사용하여 문제를 해결하십시오. js.exec ("document.getElementsByClassName ('ui-form-control ng-isolate-scope') [0] .removeAttribute ('readonly')") – Amy

+0

속성이 읽기 전용이고 수정하면 어떤 종류의 테스트입니까? 사용자가 페이지에서 수행 할 수없는 작업을 테스트하고 있습니다. 나는 그것이 무의미하다고 생각한다. 페이지를 해킹하는 대신 실제 사용자 행동을 테스트하는 데 집중하십시오. 또는 Geb을 테스트 툴이 아닌 브라우저 자동화 및 페이지 해킹 툴로 사용합니까? 이 경우 Geb가 발명 된 것이 아니더라도 질문을 이해합니다. – kriegaex

+0

kriegaex, 실제로 xpath를 사용하여 datepicker (angular)의 요소 (날짜, 월)를 가져올 수 없으므로 datepicker의 값을 직접 설정하려고합니다. 그러나 그것은 당신이 클릭하는 가치만을 받아들이는 것처럼 보입니다. 나는 여전히 datepicker에 대한 가치를 설정하는 방법을 찾지 못한다. – Amy

답변

0

을, 내가 배우고 싶었다 나는 무엇이든지 가치있는 것이기 때문에 그것을 당신과 함께 나누고 있습니다.

JS를 사용하지 않고 Geb 또는 Selenium을 통해 Angular datepicker에서 정보를 수집하고 상호 작용하는 Geb 테스트입니다. 이 시험 방법을 보여줍니다에

  1. myNavigator.singleElement().getAttribute("value")를 통해 날짜 선택기의 텍스트 필드에서 현재 선택한 날짜 (또한 비활성 컨트롤 작동),
  2. 를 얻을 날짜 선택기를 열고에서 강조 표시된 날짜를 찾아 현재 선택한 날짜를 얻을 달력 (전용 물론, 활성 컨트롤 작동),
  3. 오히려 지루의 날짜 선택기를 열고
    • 하여 현재 올해의 크리스마스의 날 (12 월 25)을 선택하여 날짜 선택기로
    • 상호 작용 해 선택의 달을 열기 위해 현재 월에
    • 클릭, 12 월
    • 클릭하면, 효과적으로
    • 마침내 여부를 확인, 효과적으로 다시 날짜 선택기를 마감, 하루 25에 다시
    • 클릭을 달 선택 닫기 올바른 날짜는 예 # 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는 나쁜 테스트를 초래할 것이다).

업데이트 : 페이지 개체를 사용하여 코드를 리팩터링했습니다.

+0

업데이트 : 코드를 리팩토링하여 페이지 개체를 사용했습니다. – kriegaex

+0

도움 주셔서 대단히 감사합니다! 스크립트가 내 문제를 해결할 수 있도록 안내합니다. 이제는 사용자가 편집 할 요소 대신 페이지와 상호 작용합니다. – Amy

1

WebDriver 때문에.

the js object을 통해 javascript를 사용해야합니다. Geb's jQuery integration 덕분에 페이지에 jQuery가로드되어 있으면 더 쉽게 수행 할 수 있습니다. 다음 코드

+0

답장을 보내 주셔서 감사합니다. 내 페이지에 JQuery가로드되어 있지 않은 경우 어떻게 요소를 읽기 전용으로 제거하거나 값을 전송할 수 있습니까? – Amy

+0

javascript의 ['Element.removeAttribute()'] (https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute)를 사용하고 싶습니다. – erdi

+0

도움을 주셔서 감사합니다. 문제를 해결했습니다. 아래 답변을 참조하십시오. – Amy

0

를 사용하여이 문제를 해결하려면 다음과 영업 이익은 그것이 AngularJS와 날짜 선택기했다 내가 각도, 자신이 프런트 엔드 사람이없는 어떤 접촉 한 적이 있기 때문에

js.exec(
    "document.getElementsByClassName('ui-form-control ng-isolate-scope')[0]" + 
    ".removeAttribute('readonly')" 
)