Alkemy
A browser automation framework written in Kotlin, based on Selenium and Kotest
Install / Use
/learn @resoluteworks/AlkemyREADME
Alkemy
Alkemy is a browser automation framework written in Kotlin and based on Selenium and Kotest. The objective is to provide more fluent definitions for Selenium tests, using a functional style and Kotlin extension functions. Alkemy currently supports Chrome and Firefox browsers.
Feature highlights
- Extension functions and assertions
- Custom test selector
- Reports
- Run multiple browsers in parallel
- Spring Boot Module. Contributed by @daniel-shuy.
Documentation
- Reference documentation
- Various test examples
- Full working project setup
- Spring boot integration
- API Docs - Alkemy core
- API Docs - Alkemy Spring
Dependency
testImplementation "io.resoluteworks:alkemy:${alkemyVersion}"
Usage
class MyTest : StringSpec({
val context = defaultAlkemyContext()
String selectors
A set of extensions functions can be used against String to perform lookups and assertions.
class MyTest : StringSpec({
val context = defaultAlkemyContext()
"string selectors and assertions" {
// To use String extensions the context.apply{} construct is required
context.apply {
get("/dynamic_controls")
val form = "#input-example"
"$form button".shouldHaveText("Enable")
.shouldBeEnabled()
.click()
.shouldBeDisabled()
"$form #loading".shouldBeVisible()
"$form input[type='text']".shouldBeEnabled(maxWaitSeconds = 10)
}
}
WebDriver & WebElement extensions
Similar extensions are available for WebDriver and WebElement, including
helper methods like fillForm, typeIn and assertions like shouldBeVisible, shoulHaveClass, etc.
"login with fillForm" {
context.get("/login")
.fillForm(
"username" to "tomsmith",
"password" to "SuperSecretPassword!"
)
.submit() shouldHaveText "Welcome to the Secure Area"
}
Custom test selector attribute
Alkemy can use a globally defined data-* HTML attribute to lookup elements.
Read more about this here.
<body>
<div data-test-selector="content-div">Secure area</div>
<div>Footer</div>
</body>
byTestSelector("content-div").text shouldBe "Secure area"
Or
"[${testSelector}=content-div]".text shouldBe "Secure area"
Please note this is only available within a context.apply{} block.
Page Object Model
Alkemy also provides a very basic framework for Page Object Model approaches. This includes all the extensions and
assertions available for WebDriver.
class LoginPage(context: AlkemyContext) : Page(context, "/login") {
fun login(username: String, password: String): SecurePage {
fillForm("username" to username, "password" to password)
.submit()
return next<SecurePage>()
}
}
class SecurePage(context: AlkemyContext) : Page(context, "/secure")
"login with page object model" {
val securePage = context
.goTo<LoginPage>()
.login("tomsmith", "SuperSecretPassword!")
securePage shouldHaveText "Welcome to the Secure Area"
}
Using native Kotest assertions
Any Kotest assertions can be used natively in combination with the Alkemy or Selenium objects.
"using native Kotest assertions" {
val driver = context.get("/login")
driver.findElements("input") shouldHaveSize 2
driver.find("h2").text shouldContain "Login Page"
}
Custom Alkemy Config
Example to customize the Alkemy config for a Spec:
class MyTest : StringSpec({
val context = customAlkemyContext(
AlkemyConfig(baseUrl = baseUrl),
)
})
To customize the default Alkemy config for a Spec, use AlkemyConfig's copy constructor to overwrite any properties,
e.g.
class MyTest : StringSpec({
val context = customAlkemyContext(
AlkemyConfig.fromSystemProperties().copy(
browser = Browser.FIREFOX,
headless = true,
windowWidth = 800,
windowHeight = 600,
),
)
})
Disabling Kotest Auto Scan
If Kotest auto scan is disabled, to enable
pooling, you will need to manually load the AlkemyWebDriverPoolExtension extension in your Project config, e.g.
class ProjectConfig : AbstractProjectConfig() {
override fun extensions() = listOf(AlkemyWebDriverPoolExtension)
}
Documentation
See Documentation for further information.
Related Skills
node-connect
350.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.9kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
350.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
350.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
