Automating form input with Selenium IDE

A form is the most common means of collecting user information on the internet. When implemented well, they can be simple to use particularly when the requested data is short and easy to enter. More complex data is usually better collected through other means such as structured file imports. However, some tools do not support these options and as a consumer, you're left with either finding a different tool or manually entering the data.

I recently found myself in this situation while working on my tax return. My preparation tool of choice did not support mass data import for trades. The only options available were forms that would have required me to fill in hundreds of entries.

Cash App Taxes - Capital Gains Entry Form[1]

However, with a bit of creativity and scripting know-how, I was surprised at how easy it was to automate the data entry using Selenium.

Selenium is a browser automation framework with several tools and APIs for automating user interaction on web apps. It was originally designed as a test automation framework but can be used for general automation tasks as well. The Selenium tool suite includes the Selenium IDE browser extension[2] which can be used to record and execute test cases.

Selenium IDE projects are stored as *.side files. On closer inspection, these are just JSON files that contain information about test cases and suites.

{
  "id": "d174a700-2ca0-42de-b10e-e2c7ea5e70a0",
  "version": "2.0",
  "name": "sample",
  "url": "",
  "tests": [{
    "id": "6d4bacf4-8d87-4b3f-8a82-e80e11e3f732",
    "name": "Untitled",
    "commands": []
  }],
  "suites": [{
    "id": "92c24923-4db6-4f81-88a3-97ef38ebaf7d",
    "name": "Default Suite",
    "persistSession": false,
    "parallel": false,
    "timeout": 300,
    "tests": ["6d4bacf4-8d87-4b3f-8a82-e80e11e3f732"]
  }],
  "urls": [],
  "plugins": []
}
Sample Selenium IDE project

Since all of this is driven by JSON, with a little scripting know-how, it's trivial to generate this in almost any scripting language. Let's explore this by automating a simple Google Form.

Every action in our tests is represented as a command[3]. Since we want to enter some data in the "Name" field, we want to use the type command. This requires us to provide a target. This will be the DoM element that receives the typed value.  As a result, we'll need to identify the component on the page. Fortunately, Selenium IDE comes with a built-in way of determining these values visually using the "Select target in page" tool. This works just like the inspector in the browser's Dev Console by allowing you to select a target on the page. Selecting the Name input field gives us a few options in the drop-down.

We can use either of these as our target. If you were attempting to enter data into a table-like structure, using a value that contains a convenient index may be the most convenient. However, the css:finder value will work just fine for our needs.

We're now ready to set up a simple project. I'm working in Node.JS but this will translate well into any scripting language. The boilerplate here is needed to create a simple Selenium IDE project declaring a single test suite with no tests (we'll be filling that part out shortly.

const fs = require("fs");
const { v4 } = require('uuid');

const project = {
    id: v4(),
    version: "2.0",
    name: "sample project",
    url: "https://docs.google.com/forms/d/e/1FAIpQLSfzBW_DzfahySH03j4YSSBmaPnMMdJ8Ka0V2CvtXXuvU8iOhQ/viewform",
    tests: [],
    suites: [
        {
            id: v4(),
            name: "Default Suite",
            persistSession: false,
            parallel: false,
            timeout: 300,
            tests: []
        }
    ],
    urls: [
        "https://docs.google.com/forms/d/e/1FAIpQLSfzBW_DzfahySH03j4YSSBmaPnMMdJ8Ka0V2CvtXXuvU8iOhQ/viewform"
    ],
    plugins: []
};

We can create the test that we will be running. Here I'm calling it "sample", but you may call it whatever you like.

const test = {
    id: v4(),
    name: "sample",
    commands: []
};

Now we need to add a command which will open the form. This should be added to the test we just created.

test.commands.push({
    id: v4(),
    comment: "",
    command: "open",
    target: "https://docs.google.com/forms/d/e/1FAIpQLSfzBW_DzfahySH03j4YSSBmaPnMMdJ8Ka0V2CvtXXuvU8iOhQ/viewform",
    targets: [],
    value: ""
});

Now we can add our type command using the selector we determined earlier

test.commands.push({
    id: v4(),
    comment: "",
    command: "type",
    target: "css=.Qr7Oae:nth-child(1) .whsOnd",
    targets: [],
    value: "Hello Selenium IDE!"
});

Finally, we need to add our test to the project and then generate our output file.

project.tests.push(test);
fs.writeFileSync("out.side", JSON.stringify(project, null, 2));

We can open this generated project in Selenium IDE and execute the test to see it in action.

Conclusion

Automating the boring stuff is always an incredibly exciting and fulfilling challenge. This is especially true when it's a flexible and repeatable solution. Given the ever-increasing amount of utilities that run our lives moving to the internet, being familiar with a web automation framework has the potential to yield incredible value and is something I'd encourage every engineer to invest a least some time in.


  1. Rounds, H. (2022). Cash App Taxes Review 2022 (Formerly Credit Karma Tax). [online] The College Investor. Available at: https://thecollegeinvestor.com/39045/cash-app-taxes-review/ [Accessed 18 Apr. 2022].
  2. selenium.dev. (n.d.). Selenium IDE · Open source record and playback test automation for the web. [online] Available at: https://www.selenium.dev/selenium-ide/.
  3. ui.vision. (n.d.). Selenium IDE Commands 2021 - Overview and Tutorials. [online] Available at: https://ui.vision/rpa/docs/selenium-ide [Accessed 18 Apr. 2022].

Subscribe to Another Dev's Two Cents

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe