dequelabs / axe-core

Accessibility engine for automated Web UI testing
https://www.deque.com/axe/
Mozilla Public License 2.0
5.87k stars 763 forks source link

Working with elements inside an iframe #4567

Open BurovnikovEvgeniy opened 3 weeks ago

BurovnikovEvgeniy commented 3 weeks ago

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)

Zidious commented 3 weeks ago

Hey @BurovnikovEvgeniy!

We're looking into it and will respond shortly

Zidious commented 3 weeks ago

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();