我如何 test/validate cypress 中某个部分的 header 层次结构?
How can I test/validate the header hierarchy of a section in cypress?
我想强制执行 header 遵循层次结构的结构。意思是如果你从 dom 的底部到顶部,下一个标题必须 <= 当前或 + 1.
这是我的其中一个部分标题的控制台日志,例如:
Yielded:
0: h2.mt-4
1: h3.mt-16.text-base.w-64
2: h4.mt-0.font-normal.text-sm
3: h4.mt-0.font-normal.text-sm
4: h4.mt-0.font-normal.text-sm
5: h3.mt-16.text-base.w-64
6: h4.mt-0.font-normal.text-sm
7: h4.mt-0.font-normal.text-sm
8: h4.mt-0.font-normal.text-sm
9: h4.mt-0.font-normal.text-sm
10: h3.mt-16.text-base.w-64
11: h4.mt-0.font-normal.text-sm
12: h4.mt-0.font-normal.text-sm
这是有效的^
Yielded:
0: h2.mt-4
1: h3.mt-16.text-base.w-64
2: h4.mt-0.font-normal.text-sm
3: h4.mt-0.font-normal.text-sm
4: h4.mt-0.font-normal.text-sm
5: h3.mt-16.text-base.w-64
6: h4.mt-0.font-normal.text-sm
7: h4.mt-0.font-normal.text-sm
8: h4.mt-0.font-normal.text-sm
9: h4.mt-0.font-normal.text-sm
10: h3.mt-16.text-base.w-64
11: h1.mt-0.font-normal.text-sm
12: h1.mt-0.font-normal.text-sm
这不是^^^
到目前为止,我可以遍历各个部分并获取每个部分 headers,但对如何遍历并强制执行该规则有点困惑。这需要比较当前 header 和数组中的下一个
我目前拥有的:
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.get($section).within(() => {
cy.get("h1,h2,h3,h4,h5,h6"); //now what?...
});
});
});
@agoff:console.log
向我们展示了第一个 $el,然后是 $list[index + 1]:
This is the $el: jQuery.fn.init [h2.mt-4]
This is the $el: <h3 data-cy="header" class="mt-16 text-base w-64">Engineering</h3>
@agoff:这行得通,但它很笨拙:
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.get($section).within(() => {
cy.get("h1,h2,h3,h4,h5,h6").each(($el, index, $list) => {
// Don't run the validation on the last item in the list
if (index !== $list.length - 1) {
// Get the size of the current and next header
const currSize = getHeaderNumber($el);
const nextSize = getHeaderNumber($list, index + 1);
try {
expect(currSize <= nextSize || currSize + 1 === nextSize).to.eql(
true
);
} catch {
console.log("Failed on current size:", currSize);
console.log("Failed on next size:", nextSize);
throw error;
}
}
});
});
});
});
// helper function to get header number
const getHeaderNumber = ($el, index) => {
console.log("Going to parse this:", $el.get(index ?? 0));
try {
console.log("Got this:", parseInt($el.get(index ?? 0).tagName.slice(1)));
return parseInt($el.get(index ?? 0).tagName.slice(1));
} catch {
console.log("ERROR ON:", $el.get(index ?? 0));
}
};
您可以生成所生成元素的索引,以及整个列表。使用它,我们可以轻松比较下一个生成的项目。
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.wrap($section).within(($sectionWithin) => {
cy.get("h1,h2,h3,h4,h5,h6").each(($el, index, $list) => {
// Don't run the validation on the last item in the list
if (index !== $list.length - 1) {
// Get the size of the current and next header
const currSize = getHeaderNumber($el)
const nextSize = getHeaderNumber($list[index + 1])
expect(currSize <= nextSize || currSize + 1 === nextSize).to.eql(true);
}
});
});
});
});
// helper function to get header number
const getHeaderNumber = ($el) => {
const tagName = $el.prop('tagName') ?? $el.get(0).tagName
return parseInt(tagName.slice(1), 10);
}
我想强制执行 header 遵循层次结构的结构。意思是如果你从 dom 的底部到顶部,下一个标题必须 <= 当前或 + 1.
这是我的其中一个部分标题的控制台日志,例如:
Yielded:
0: h2.mt-4
1: h3.mt-16.text-base.w-64
2: h4.mt-0.font-normal.text-sm
3: h4.mt-0.font-normal.text-sm
4: h4.mt-0.font-normal.text-sm
5: h3.mt-16.text-base.w-64
6: h4.mt-0.font-normal.text-sm
7: h4.mt-0.font-normal.text-sm
8: h4.mt-0.font-normal.text-sm
9: h4.mt-0.font-normal.text-sm
10: h3.mt-16.text-base.w-64
11: h4.mt-0.font-normal.text-sm
12: h4.mt-0.font-normal.text-sm
这是有效的^
Yielded:
0: h2.mt-4
1: h3.mt-16.text-base.w-64
2: h4.mt-0.font-normal.text-sm
3: h4.mt-0.font-normal.text-sm
4: h4.mt-0.font-normal.text-sm
5: h3.mt-16.text-base.w-64
6: h4.mt-0.font-normal.text-sm
7: h4.mt-0.font-normal.text-sm
8: h4.mt-0.font-normal.text-sm
9: h4.mt-0.font-normal.text-sm
10: h3.mt-16.text-base.w-64
11: h1.mt-0.font-normal.text-sm
12: h1.mt-0.font-normal.text-sm
这不是^^^
到目前为止,我可以遍历各个部分并获取每个部分 headers,但对如何遍历并强制执行该规则有点困惑。这需要比较当前 header 和数组中的下一个
我目前拥有的:
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.get($section).within(() => {
cy.get("h1,h2,h3,h4,h5,h6"); //now what?...
});
});
});
@agoff:console.log
向我们展示了第一个 $el,然后是 $list[index + 1]:
This is the $el: jQuery.fn.init [h2.mt-4]
This is the $el: <h3 data-cy="header" class="mt-16 text-base w-64">Engineering</h3>
@agoff:这行得通,但它很笨拙:
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.get($section).within(() => {
cy.get("h1,h2,h3,h4,h5,h6").each(($el, index, $list) => {
// Don't run the validation on the last item in the list
if (index !== $list.length - 1) {
// Get the size of the current and next header
const currSize = getHeaderNumber($el);
const nextSize = getHeaderNumber($list, index + 1);
try {
expect(currSize <= nextSize || currSize + 1 === nextSize).to.eql(
true
);
} catch {
console.log("Failed on current size:", currSize);
console.log("Failed on next size:", nextSize);
throw error;
}
}
});
});
});
});
// helper function to get header number
const getHeaderNumber = ($el, index) => {
console.log("Going to parse this:", $el.get(index ?? 0));
try {
console.log("Got this:", parseInt($el.get(index ?? 0).tagName.slice(1)));
return parseInt($el.get(index ?? 0).tagName.slice(1));
} catch {
console.log("ERROR ON:", $el.get(index ?? 0));
}
};
您可以生成所生成元素的索引,以及整个列表。使用它,我们可以轻松比较下一个生成的项目。
Cypress.Commands.add("checkHeadingHeirarchy", () => {
cy.get("section").each(($section) => {
cy.wrap($section).within(($sectionWithin) => {
cy.get("h1,h2,h3,h4,h5,h6").each(($el, index, $list) => {
// Don't run the validation on the last item in the list
if (index !== $list.length - 1) {
// Get the size of the current and next header
const currSize = getHeaderNumber($el)
const nextSize = getHeaderNumber($list[index + 1])
expect(currSize <= nextSize || currSize + 1 === nextSize).to.eql(true);
}
});
});
});
});
// helper function to get header number
const getHeaderNumber = ($el) => {
const tagName = $el.prop('tagName') ?? $el.get(0).tagName
return parseInt(tagName.slice(1), 10);
}