admin管理员组

文章数量:1294662

I want to use mermaid.js to render a flowchart. I want to use the Selenium driver in Java to read the rendered HTML DOM. However, the HTML source is read when the rendering is not complete. How can I achieve it?

HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <script type="module">
    import mermaid from '/[email protected]/+esm'
    const config = {
          startOnLoad: true,
          flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
          securityLevel: 'loose',
    };
    mermaid.initialize(config);         
  </script>
</head>
<body>
    <div class="mermaid">
        flowchart TD
            A --> B
    </div>
</body>
</html>

I want to use mermaid.js to render a flowchart. I want to use the Selenium driver in Java to read the rendered HTML DOM. However, the HTML source is read when the rendering is not complete. How can I achieve it?

HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <script type="module">
    import mermaid from 'https://cdn.jsdelivr/npm/[email protected]/+esm'
    const config = {
          startOnLoad: true,
          flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
          securityLevel: 'loose',
    };
    mermaid.initialize(config);         
  </script>
</head>
<body>
    <div class="mermaid">
        flowchart TD
            A --> B
    </div>
</body>
</html>

Java code:

package com.tugalsan.tst.html;

import static java.lang.System.out;
import java.nio.file.Path;
import java.time.Duration;
import .openqa.selenium.Dimension;
import .openqa.selenium.JavascriptExecutor;
import .openqa.selenium.WebDriver;
import .openqa.selenium.edge.EdgeDriver;
import .openqa.selenium.edge.EdgeOptions;
import .openqa.selenium.firefox.FirefoxDriver;
import .openqa.selenium.firefox.FirefoxOptions;
import .openqa.selenium.support.ui.ExpectedCondition;
import .openqa.selenium.support.ui.Wait;
import .openqa.selenium.support.ui.WebDriverWait;

public class Main {

    public static void main(String... args) {
        var urlPath = Path.of("C:\\git\\tst\\com.tugalsan.tst.html\\a.html");
        var urlStr = urlPath.toUri().toString();
        var until = Duration.ofMinutes(1);
        var output = processHTML(urlStr, until, false, false);
        out.println(output);
    }

    public static String processHTML(String urlStr, Duration until, boolean useFirefox, boolean useWait) {
        WebDriver driver = null;
        if (useFirefox) {
            try {
//                    WebDriverManager.firefoxdriver().setup();
                var options = new FirefoxOptions();
                options.addArguments("--no-sandbox");
//                    options.setExperimentalOption("useAutomationExtension", false);
//                    options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
                options.addArguments("--disable-infobars"); // disabling infobars
                options.addArguments("--disable-gpu"); // applicable to windows os only
                options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
                options.addArguments("--disable-popup-blocking");
                options.setAcceptInsecureCerts(true);
//                    options.addArguments("--disable-blink-features=AutomationControlled");
                driver = new FirefoxDriver(options);
                if (useWait) {
                    waitForPageToLoad(driver, until);
                }
                driver.get(urlStr);
                return driver.getPageSource();
            } finally {
                if (driver != null) {
                    driver.close();
                }
                if (driver != null) {
                    driver.quit();
                }
            }
        }

        var options = new EdgeOptions();
        options.addArguments("--no-sandbox");
        options.setExperimentalOption("useAutomationExtension", false);
        options.setExperimentalOption("excludeSwitches", new String[]{"enable-automation"});
        options.addArguments("--disable-infobars"); // disabling infobars
        options.addArguments("--disable-gpu"); // applicable to windows os only
        options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
        options.addArguments("--disable-popup-blocking");
        options.setAcceptInsecureCerts(true);
        options.addArguments("--disable-blink-features=AutomationControlled");

        try {
            driver = new EdgeDriver(options);
            if (useWait) {
                waitForPageToLoad(driver, until);
            }
            driver.manage().timeouts().implicitlyWait(until);
            driver.manage().timeouts().pageLoadTimeout(until);
            var dmn = new Dimension(1280, 1024);
            driver.manage().window().setSize(dmn);
            driver.get(urlStr);
            return driver.getPageSource();
        } finally {
            if (driver != null) {
                driver.close();
            }
            if (driver != null) {
                driver.quit();
            }
        }
    }

    public static void waitForPageToLoad(WebDriver driver, Duration until) {
        ExpectedCondition< Boolean> pageLoad = (WebDriver driver1) -> ((JavascriptExecutor) driver1).executeScript("return document.readyState").equals("complete");
        Wait< WebDriver> wait = new WebDriverWait(driver, until);
        try {
            wait.until(pageLoad);
        } catch (Throwable pageLoadWaitError) {
            throw new RuntimeException(pageLoadWaitError);
        }
    }

}

HTML output:

<html lang="en"><head>
  <meta charset="utf-8">
  <script type="module">
    import mermaid from 'https://cdn.jsdelivr/npm/[email protected]/+esm'
  </script>
</head>
<body>
    <div class="mermaid" data-processed="true">
        <div id="dmermaid-1739357573062" style="font-family: &quot;trebuchet ms&quot;, verdana, arial, sans-serif;">    
            <svg id="mermaid-1739357573062" width="100%" xmlns="http://www.w3./2000/svg" xmlns:xlink="http://www.w3./1999/xlink">
                <g></g>
            </svg>
        </div>
    </div>
</body></html>
Share Improve this question edited Feb 12 at 11:48 Mark Rotteveel 109k229 gold badges156 silver badges220 bronze badges asked Feb 12 at 11:15 Tugalsan KarabacakTugalsan Karabacak 6539 silver badges20 bronze badges 2
  • 2 your "until" is not defined correctly. You need to use a webdriverwait that has a condition that is only true once the page is loaded. You can then call driver.getPageSource(); The order is also incorrect... the wait should be after the .get() call (that will wait for a standard page load), and before driver.getPageSource(). (since this page appears to lazy-load some stuff, i.e.: update the DOM after a standard page load happens) You could alternatively just use a sleep after the .get() call that is long enough for the lazy-loaded content to appear in the DOM. – browsermator Commented Feb 12 at 19:30
  • @browsermator I could not able to fix it with a smart wait. But Thread.sleep(X) before get works. Thx – Tugalsan Karabacak Commented Feb 14 at 3:30
Add a comment  | 

1 Answer 1

Reset to default 1

As @browsermator answered putting sleep before get works.

package com.tugalsan.tst.html;

import static java.lang.System.out;
import java.nio.file.Path;
import java.time.Duration;
import .openqa.selenium.Dimension;
import .openqa.selenium.WebDriver;
import .openqa.selenium.edge.EdgeDriver;
import .openqa.selenium.edge.EdgeOptions;

public class Main {

    public static void main(String... args) throws InterruptedException {
        var urlPath = Path.of("C:\\git\\tst\\com.tugalsan.tst.html\\a.html");
        var urlStr = urlPath.toUri().toString();
        var until = Duration.ofSeconds(15);
        var scrnSize = new Dimension(640, 480);
        var output = processHTML(urlStr, until, scrnSize);
        out.println(output);
    }

    public static String processHTML(String urlStr, Duration until, Dimension scrnSize) throws InterruptedException {
        WebDriver driver = null;
        try {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
            driver.manage().timeouts().implicitlyWait(until);
            driver.manage().timeouts().pageLoadTimeout(until);
            driver.manage().window().setSize(scrnSize);
            driver.get(urlStr);
            Thread.sleep(until);
            return driver.getPageSource();
        } finally {
            if (driver != null) {
                driver.quit();
            }
        }
    }
}

本文标签: google chromeSelenium driver is not waiting for the page to load on Java for mermaidjsStack Overflow