Load Test Your App Using Real Browsers.

Flood Element is the first scalable, browser based load generation tool — making load testing as easy as functional testing.

View the docsGitHub

License: Apache 2 • v1.0.5-beta.0

Features

Flood Element is the best way to get started with load testing.

  • Realistic Load

    Working at a higher level of abstraction greatly simplifies the requests you need to make to simulate users on your application.

  • Test Data

    Load testing without test data is like using lorem ipsum in production. Element ships with rich support for CSV and JSON data loading.

  • Selenium Compatible

    Element's DSL is heavily influenced by WebDriver.js, making it really easy to migrate your Selenium scripts to Element.

  • Built on Puppeteer

    Thanks to the speed of the Puppeteer automation library, Element generates load by launching thousands of instances of Google Chrome.

  • TypeScript

    TypeScript gives you inline documentation and script validation before pressing launch, to catch the small issues which might stop the show.

  • Command Line Interface

    Generate new tests, validate, and run them locally, with our interactive CLI.

import { step, By, Until, TestSettings, TestData } from '@flood/element'
import * as assert from 'assert'

export const settings: TestSettings = {
  clearCache: false,
  clearCookies: false,
  responseTimeMeasurement: 'step',
  userAgent: 'I AM ROBOT',
  actionDelay: 1,
  stepDelay: 1,
}

let data = [{ age: 42 }, { age: 16 }, { age: 29 }, { age: 54 }, { age: 31 }]

interface Row {
  age: number
}

TestData.fromData<Row>(data)
  .shuffle()
  .circular()

export default () => {
  step('1. Start', async browser => {
    await browser.visit('https://challenge.flood.io')

    let button = By.css('#new_challenger > input.btn.btn-xl.btn-default')
    await browser.wait(Until.elementIsVisible(button))

    await browser.takeScreenshot()
    await browser.click(button)
  })

  step('2. Age', async (browser, row: Row) => {
    let select = By.id('challenger_age')
    await browser.wait(Until.elementIsVisible(select))
    await browser.selectByValue(select, row.age.toString())

    await browser.takeScreenshot()

    await browser.click('input.btn')
  })

  step('3. Largest Order', async browser => {
    let table = By.css('table tbody tr td:first-of-type label')
    await browser.wait(Until.elementIsVisible(table))

    let orderElements = await browser.findElements(table)
    assert(orderElements.length > 0, 'expected to find orders on this page')

    let orderIDs = await Promise.all(
      orderElements.map(element => element.text()),
    )

    // Find largest number by sorting and picking the first item
    let largestOrder = orderIDs
      .map(Number)
      .sort((a, b) => a - b)
      .reverse()[0]

    // Click label with order ID
    await browser.click(By.visibleText(String(largestOrder)))

    // Fill in text field
    let field = By.id('challenger_largest_order')
    await browser.type(field, String(largestOrder))

    await browser.takeScreenshot()
  })

  step('4. Easy', async browser => {
    await browser.click('input.btn')

    await browser.takeScreenshot()
  })

  step('5. One Time Token', async browser => {
    await browser.click('input.btn')

    await browser.wait(Until.elementTextMatches('span.token', /\d+/))
    let element = await browser.findElement('span.token')
    let token = await element.text()
    await browser.type(By.id('challenger_one_time_token'), token)

    await browser.takeScreenshot()
  })

  step('6. Done', async browser => {
    await browser.click('input.btn')

    await browser.wait(Until.elementIsVisible('h2'))
    let element = await browser.findElement('h2')
    let completionText = await element.text()
    assert.equal(completionText, "You're Done!")

    await browser.takeScreenshot()
  })
}

Test Smarter.

Load testing at the browser level opens up huge opportunities for testing modern web applications which would be extremely difficult to achieve reliably with existing network level load testing tools.

  • Reduce maintenance

    Flood Element scripts are less prone to breakage compared with JMeter or Gatling scripts.

  • Save time

    It takes just a few minutes to get functional load test running with Flood Element.

  • Generate Realistic Load

    In today's modern applications, up to 80% of performance problems occur in the browser, which makes browser based load testing more important than ever.

Browser vs. Protocol

Load testing has barely kept pace with the rate of innovation on the web as a platform over the last 20 years. We set out to change this with Flood Element.

Traditionally, load testing meant simulating network calls as quickly as possible, either using scripting, log replay, or a network recorder. But these approaches have always suffered from a high cost of script maintenance due to the fickle nature of network requests, lack of maintenance due to complexity, or simulating unrealistic load due to a misunderstanding of the workload patterns of regular users of the product.

These are just some of the problems we're solving by load testing in a similar way to real users of your application.

Get Started