Working with elements inside an iframe
Product
axe-core
Question
Hello, I'm trying to check the element(s) that are inside the iframe, but I don't understand how to do it normally. I keep catching the error no such element: element not found (Session info: chrome=127.0.6533.120).
What is there? There is a page where the DOM tree looks something like this:
<div id="pmntWzrdCtr"....>
<iframe class="modal-new_payment-frame" ....>
#document(...)
<head></ head>
<body>
<div id="hook_Block_SendBlock" class="hookBlock">...</div>
</ body>
</iframe>
</div>
This is a rough outline of the page code, I tried to omit all the details, but left the structure
I tried to work with an iframe like this:
WebDriver driver = getWebDriver().switchTo().frame(getWebDriver().findElement(By.cssSelector("#pmntWzrdCtr iframe")));
getA11Y().testA11Y(driver, $(By.cssSelector("#hook_Block_SendBlock")));
In getA11Y I configure the operation of axe
axeBuilder = new AxeBuilder().setLegacyMode();
axeBuilder.withTags(Arrays.asList("wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "best-practice", "cat.structure", "review-item"));
axeBuilder.disableRules(Arrays.asList(...));
And in the testA11Y function, I run the analysis
Results axeResults = axeBuilder.analyze(driver, selenideElement);
List<Rule> rules = axeResults.getViolations();
I tried to run the analysis in various ways, including using include, but it didn't help https://dequeuniversity.com/rules/axe/4.9/frame-tested?application=axeAPI https://github.com/dequelabs/axe-core-maven-html/blob/develop/playwright/README.md#limit-frame-testing
Unfortunately, all this did not help me achieve the desired goal, in general, there are quite a few (as it seems to me) examples in the documentation, which raises questions
(com.deque.html.axe-core:selenium:4.9.1)
Hey @BurovnikovEvgeniy!
We're looking into it and will respond shortly
The error you're getting: error no such element: element not found appears to be coming from Selenium not axe-core-maven-html-selenium package. Using the fromFrames API (docs) you can limit the testing scope to elements within your iframe. Below I have an example page that has an iframe element and a class attribute (similar to your snippet called modal-new_payment-frame) that loads some content.
main.html -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Top-level</title>
</head>
<body>
<h1>Top level page</h1>
<iframe class="modal-new_payment-frame" src="iframe.html"></iframe>
</body>
</html>
iframe.html -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My iframe</title>
</head>
<body>
<h1>My Iframe Page</h1>
<div id="hook_Block_SendBlock">
<button></button>
<img />
</div>
</body>
</html>
To limit testing to the saidiframe and everything with the div that has an id of hook_Block_SendBlock you can do:
WebDriver webDriver = new ChromeDriver();
webDriver.get("<url>");
// Limit testing to everything with the `hook_Block_SendBlock` div within the `.modal-new_payment-frame` iframe:
AxeBuilder axeBuilder =
new AxeBuilder().include(new FromFrames(".modal-new_payment-frame", "#hook_Block_SendBlock"));
List<Rule> results = axeBuilder.analyze(webDriver).getViolations();
for (Rule rule : results) {
System.out.println(rule.getId());
System.out.println(rule.getDescription());
}
webDriver.quit();
@Zidious Do I understand correctly that we should just pass the basic element of the frame to axe and it will scan it completely (all elements) according to its own rules? For your example, I call the base element of the frame
Yes, if you want to only run within a child element within the iframe then you can use the FromFrames method. You pass in the iframe you want to test against then the child element you want to scope testing to for example: FromFrames(".my-iframe", ".my-child-iframe-div")
Yes, if you want to only run within a child element within the iframe then you can use the
FromFramesmethod. You pass in the iframe you want to test against then the child element you want to scope testing to for example:FromFrames(".my-iframe", ".my-child-iframe-div")
I understand you! Thank you very much