Элемент доступа, родитель которого скрыт-cypress.io
вопрос, как указано в заголовке, т. е. для доступа к элементу, родитель которого скрыт. Проблема в том, что, согласно Кипарис.io docs :
элемент является скрытый если:
- его ширина или высота 0.
- его свойство CSS (или предки) - visibility: hidden.
- его свойство CSS (или предки) отображается: никто.
- его свойство CSS-position: fixed, и он за кадром или закрыт.
но код, с которым я работаю, требует, чтобы я нажал на элемент,родитель скрывается, в то время как сам элемент.
поэтому каждый раз, когда я пытаюсь нажать на элемент, он выдает сообщение об ошибке:
CypressError: тайм-аут повторная попытка: ожидается ' 'быть " видимым"
этот элемент ' - это не видно, потому что его родитель ' имеет свойство CSS : 'display: none'
элемент, я работаю с dropdown item
, в которой написано pug
. Элемент является компонентом, определенным в угловой-mdc-web, который использует mdc-select
в выпадающем меню и mdc-select-item
для его элементов (элементов), к которым у меня есть доступ.
пример кода аналогичной структуры:
//pug
mdc-select(placeholder="installation type"
'[closeOnScroll]'="true")
mdc-select-item(value="false") ITEM1
mdc-select-item(value="true") ITEM2
выше ITEM1
это элемент, к которому я должен получить доступ. Это я делаю в cypress.io
следующим образом :
//cypress.io
// click on the dropdown menu to show the dropdown (items)
cy.get("mdc-select").contains("installation type").click();
// try to access ITEM1
cy.get('mdc-select-item').contains("ITEM1").should('be.visible').click();
пробовал с {force:true}
чтобы заставить элемент щелкнуть, но не повезло. Попробовали выбрать элементы с помощью {enter}
нажатие клавиши на родительском mdc-select
, но опять не повезло, как он бросает :
CypressError: cy.тип () может вызываться только в textarea или :text. Ваш тема: выбрать ...
также попытался с помощью select
команда, но это невозможно, потому что Cypress engine не может идентифицировать элемент как select
элемент (потому что его нет, внутренняя работа отличается). Он бросает :
CypressError: cy.select () можно вызвать только на a . Ваш тема: выбрать ...
на это mdc-select-menu
это родитель для mdc-select-item
обладает свойством display:none
некоторыми внутренними вычислениями при открытии раскрывающихся элементов.
это свойство перезаписываться к display:flex
, но это не помогает.
все из идей. Это работает в Selenium
, но не cypress.io
. Любая подсказка, что может быть возможным взломом для ситуации, кроме перехода на другие фреймворки или изменения кода пользовательского интерфейса?
2 ответов
после долгих nashing в зубы, я думаю, у меня есть ответ.
я думаю, что основная причина в том, что mdc-select-item
и display:flex
, что позволяет ему превышать границы его родителей (строго говоря, это похоже на неправильное применение display flex, если я правильно помню учебник, однако...).
Cypress делает много родительской проверки при определении visibilty, см. видимости.кофе!--20-->,
## WARNING:
## developer beware. visibility is a sink hole
## that leads to sheer madness. you should
## avoid this file before its too late.
...
when $parent = parentHasDisplayNone($el.parent())
parentNode = $elements.stringify($parent, "short")
"This element '#{node}' is not visible because its parent '#{parentNode}' has CSS property: 'display: none'"
...
when $parent = parentHasNoOffsetWidthOrHeightAndOverflowHidden($el.parent())
parentNode = $elements.stringify($parent, "short")
width = elOffsetWidth($parent)
height = elOffsetHeight($parent)
"This element '#{node}' is not visible because its parent '#{parentNode}' has CSS property: 'overflow: hidden' and an effective width and height of: '#{width} x #{height}' pixels."
но, при использовании .should('be.visible')
, мы застряли с родительскими свойствами, не проверяющими видимость ребенка, хотя мы действительно можем видеть ребенка.
Нам нужен альтернативный тест.
работающим
Ref С помощью jQuery.js, это одно из определений видимости самого элемента (игнорирование родительских свойств).
jQuery.expr.pseudos.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
}
поэтому мы могли бы использовать это в качестве основы для альтернативы.
describe('Testing select options', function() {
// Change this function if other criteria are required.
const isVisible = (elem) => !!(
elem.offsetWidth ||
elem.offsetHeight ||
elem.getClientRects().length
)
it('checks select option is visible', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
//cy.get('mdc-select-item').contains("ITEM1").should('be.visible') //this will fail
cy.get('mdc-select-item').contains("ITEM1").then (item1 => {
expect(isVisible(item1[0])).to.be.true
});
});
it('checks select option is not visible', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
cy.document().then(function(document) {
const item1 = document.querySelectorAll('mdc-select-item')[0]
item1.style.display = 'none'
cy.get('mdc-select-item').contains("ITEM1").then (item => {
expect(isVisible(item[0])).to.be.false
})
})
});
it('checks select option is clickable', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
//cy.get('mdc-select-item').contains("ITEM1").click() // this will fail
cy.get('mdc-select-item').contains("ITEM1").then (item1 => {
cy.get('mdc-select-item').contains("ITEM2").then (item2 => {
expect(isVisible(item2[0])).to.be.true //visible when list is first dropped
});
item1.click();
cy.wait(500)
cy.get('mdc-select-item').contains("ITEM2").then (item2 => {
expect(isVisible(item2[0])).to.be.false // not visible after item1 selected
});
});
})
сноска-использование 'then' (или 'каждый')
обычно вы используете утверждение в cypress с помощью командных цепочек, которые в основном обертывают тестируемые элементы и обрабатывают такие вещи, как повтор и ожидание изменений DOM.
однако в этом случае мы имеем противоречие между стандартным утверждением видимости .should('be.visible')
и рамки, используемые для создания страницы, поэтому мы используем then(fn)
(ref), чтобы получить доступ к развернутому DOM. Затем мы можем применить нашу собственную версию тест видимости с использованием синтаксиса ожидания stand jasmine.
получается, вы также можете использовать функцию .should(fn)
, это тоже работает
it('checks select option is visible - 2', function() {
const doc = cy.visit('http://localhost:4200')
cy.get("mdc-select").contains("installation type").click()
cy.get('mdc-select-item').contains("ITEM1").should(item1 => {
expect(isVisible(item1[0])).to.be.true
});
});
используя should
вместо then
не имеет значения в тесте видимости, но обратите внимание на should
версия может повторить функцию несколько раз, поэтому ее нельзя использовать с
документы, Cypress выберите синтаксис синтаксис
cy.get('mdc-select-item').select('ITEM1')
вам понадобится {force: true}
Как хорошо. Смотрите здесь select_spec.кофе!--5--> для примеров собственных тестов, e.g
it "can forcibly click even when element is invisible", (done) ->
select = cy.$$("select:first").hide()
select.click -> done()
cy.get("select:first").select("de_dust2", {force: true})