me.saro.selenium.ChromeDriverBuilder.kt Maven / Gradle / Ivy
package me.saro.selenium
import me.saro.selenium.comm.Utils
import me.saro.selenium.model.DownloadStrategy
import me.saro.selenium.model.PathManager
import me.saro.selenium.model.SeleniumChromeException
import me.saro.selenium.service.ChromeDriverPlus
import me.saro.selenium.service.ChromeManager
import org.openqa.selenium.Dimension
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
import java.io.File
import java.time.Duration
class ChromeDriverBuilder(
private val manageChromePath: File,
) {
companion object {
private var created = false
}
private var downloadStrategy: DownloadStrategy = DownloadStrategy.DOWNLOAD_IF_NO_VERSION
private val options: MutableSet = mutableSetOf()
private val properties: MutableMap = mutableMapOf()
private val log = Utils.getLogger(ChromeDriverBuilder::class)
fun downloadStrategy(downloadStrategy: DownloadStrategy): ChromeDriverBuilder {
this.downloadStrategy = downloadStrategy
return this
}
fun option(option: String): ChromeDriverBuilder {
assert (option.isNotBlank()) { "option is blank" }
val lof = option.lastIndexOf('=')
if (lof != -1) {
val key = option.substring(0, lof)
options.removeIf { it.startsWith(key) }
}
when (option) {
"--headless" -> throw SeleniumChromeException("The --headless option cannot be used here.\nYou can use the methods openBackground(), openWith(), or newChromeDriver() through ChromeDriverManager.")
}
options.add(option)
return this
}
fun enableRecommendChromeOptions(disabledSecurity: Boolean): ChromeDriverBuilder {
option("--user-data-dir=" + System.getProperty("java.io.tmpdir")) // Prevents socket errors.
.option("--disable-infobars") // Disables browser information bar.
.option("--disable-dev-shm-usage") // Ignores the limit on temporary disk space for the browser.
.option("--blink-settings=imagesEnabled=false") // Disables image loading.
.option("--disable-extensions")
.option("--disable-popup-blocking")
.option("--disable-gpu")
if (disabledSecurity) {
properties["webdriver.chrome.whitelistedIps"] = ""
option("--no-sandbox")
.option("--ignore-certificate-errors")
}
return this
}
@Synchronized
fun build(): ChromeDriverManager {
if (created) {
log.warning("SeleniumAllInOne is already created.\nIt is a singleton object.")
}
val pathManager = PathManager.create(manageChromePath)
ChromeManager.load(pathManager, downloadStrategy)
properties.forEach(System::setProperty)
System.setProperty("webdriver.chrome.driver", pathManager.chromedriverBinPath)
created = true
return ChromeDriverManagerImpl(pathManager.chromeBinPath, options.toSet())
}
class ChromeDriverManagerImpl(
private val chromeBinPath: String,
private val options: Set
): ChromeDriverManager {
private val log = Utils.getLogger(ChromeDriverManagerImpl::class)
override fun openWith(url: String, addOption: Set, use: ChromeDriverPlus.() -> T): T {
val driver = newChromeDriver(createChromeOptions(addOption))
try {
return use(ChromeDriverPlus(driver).apply {
windowSize(2000, 3000)
val duration = Duration.ofSeconds(20)
implicitWaitTimeout = duration
pageLoadTimeout = duration
move(url)
})
} finally {
try { driver.close() } catch (e: Exception) {}
try { driver.quit() } catch (e: Exception) {}
log.info("chrome driver closed.")
}
}
override fun newChromeDriver(chromeOptions: ChromeOptions): ChromeDriver =
ChromeDriver(chromeOptions.setBinary(chromeBinPath))
private fun createChromeOptions(addOption: Set): ChromeOptions =
ChromeOptions().apply {
options.forEach(::addArguments)
addOption.forEach(::addArguments)
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy