package jnpf.selenium.driver; import jnpf.selenium.SeleniumHelper; import jnpf.selenium.properties.SeleniumProperties; import org.openqa.selenium.*; import org.openqa.selenium.remote.AbstractDriverOptions; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.service.DriverService; import java.time.Duration; import java.util.List; import java.util.Map; public interface SeleniumBrowser> { D getDriver(); S getDriverService(); O getDriverOptions(); /** * 关闭驱动和浏览器 */ void close(); /** * 设置页面加载超时时间 */ default void setPageLoadTimeout(Duration duration) { getDriver().manage().timeouts().pageLoadTimeout(duration); } /** * 设置查找元素超时时间 */ default void setImplicaitlyWaitTimeout(Duration duration) { getDriver().manage().timeouts().implicitlyWait(duration); } /** * 设置执行脚本超时时间 */ default void setScriptTimeout(Duration duration) { getDriver().manage().timeouts().scriptTimeout(duration); } /** * 寻找元素, 若不存在抛出未找到元素异常 * 如需判断元素是否存在可调用{@link #findElements} 进行判空处理, 为空获取默认超时配置 {@link SeleniumProperties#getImplicaitlyWaitTimeout()} * * @param locator 查找条件 * @param findTimeout 最长等待时间 */ default WebElement findElement(By locator, Duration findTimeout) { findTimeout = findTimeout == null ? SeleniumHelper.getSeleniumProperties().getImplicaitlyWaitTimeout() : findTimeout; setImplicaitlyWaitTimeout(findTimeout); return getDriver().findElement(locator); } /** * 寻找元素, 未找到元素返回空 * * @param locator 查找条件 * @param findTimeout 最长等待时间, 为空获取默认超时配置 {@link SeleniumProperties#getImplicaitlyWaitTimeout()} */ default List findElements(By locator, Duration findTimeout) { findTimeout = findTimeout == null ? SeleniumHelper.getSeleniumProperties().getImplicaitlyWaitTimeout() : findTimeout; setImplicaitlyWaitTimeout(findTimeout); return getDriver().findElements(locator); } /** * 加载页面 * @param url 网页地址 * @param loadTimeout 加载超时时间, 为空获取默认超时配置 {@link SeleniumProperties#getPageLoadTimeout()} * @param newTab 新窗口打开链接 */ default void loadPage(String url, Duration loadTimeout, WindowType newTab) { if (newTab != null) { getDriver().switchTo().newWindow(newTab); } loadTimeout = loadTimeout == null ? SeleniumHelper.getSeleniumProperties().getPageLoadTimeout() : loadTimeout; setPageLoadTimeout(loadTimeout); getDriver().get(url); } /** * 执行JS脚本 * @param script 脚本内容 * @param scriptTimeout 脚本执行超时时间, 为空获取默认超时配置 {@link SeleniumProperties#getScriptTimeout()} * @param args 脚本内容参数 */ default Object executeScript(String script, Duration scriptTimeout, Object... args){ scriptTimeout = scriptTimeout == null ? SeleniumHelper.getSeleniumProperties().getScriptTimeout() : scriptTimeout; setScriptTimeout(scriptTimeout); return getDriver().executeScript(script, args); } /** * 获取最大的页面大小 */ default Dimension getDocumentSize() { Map result = (Map) getDriver().executeScript("return {'w':Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth), 'h':Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight)}"); return new Dimension(Math.toIntExact(result.get("w")), Math.toIntExact(result.get("h"))); } /** * 窗口最大化, 截取全部网页内容 */ default byte[] screenShotByWindow() { getDriver().manage().window().setSize(getDocumentSize()); return getDriver().getScreenshotAs(OutputType.BYTES); } /** * 窗口最大化, 截取指定元素 */ default byte[] screenShotByElement(WebElement element) { getDriver().manage().window().setSize(getDocumentSize()); return element.getScreenshotAs(OutputType.BYTES); } /** * 可能存在懒加载, 滚动页面到底部进行触发, 每次滚动完后延时指定时间等待触发 * @param scrollDelay 每次滚动完后延时, 等待触发 */ default void scrollToBottom(Duration scrollDelay) { Dimension documentSize = getDocumentSize(); long height = documentSize.getHeight(); //这里需要模拟滑动,有些是滑动的时候才加载的 long temp_height = 0; while (true) { temp_height += 500; if (temp_height >= height) { break; } getDriver().executeScript("window.scrollBy(0,500)"); try { Thread.sleep(scrollDelay.toMillis()); } catch (Exception e) { } } } }