Home
Softono

Alkemy

Open source Apache-2.0 Kotlin
17
Stars
1
Forks
0
Issues
1
Watchers
1 year
Last Commit

 About Alkemy

A browser automation framework written in Kotlin, based on Selenium and Kotest

Platforms

Web Self-hosted Android

Languages

Kotlin

Links

Need Help Installing Alkemy?

We provide expert installation service for this software. Our team will install, configure, and secure Alkemy on your server. plans start at just $30.

2023-04-24_18-26-03

Alkemy

GitHub release (latest by date) Coveralls

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

Documentation

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.