1

I'm trying to use Selenium WebDriver (in Python) to automate testing of some React code (learning BDD) and I am running into a strange issue with a bit of testing I'm trying to do.

I wrote a small app that has a counter component. There's a bit of text, then one button that increases by one, one decreases.

Here's the counter component that's being tested:

import React from 'react';

type CounterState = {
    counter: number
}

export default class Counter extends React.Component<{}, CounterState> {

    constructor(props: any) {
        super(props);
        this.state = {
            counter: 5
        }
    }

    handleIncrease(event: any) {
        this.setState({
            counter: this.state.counter + 1
        })
    }

    handleDecrease(event: any) {
        this.setState({
            counter: this.state.counter - 1
        })
    }

    render() {
        return (
            <div>
                <h2 id="counterText">Counter: { this.state.counter }!</h2>
                <button
                    id="incButton"
                    onClick = { e => this.handleIncrease(e) }
                >Increase Counter</button>
                <button
                    id="decButton"
                    onClick = { e => this.handleDecrease(e) }
                >Decrease Counter</button>
            </div>
        )
    }

}

This is the Gherkin .feature file for the Selenium test:

Feature:  Counter Test
    Scenario: Open Counter Page
        Given the counter page is not loaded
        When we click the counter navigation link
        Then the counter page is loaded
        And the counter state has the correct default
    Scenario: Increase Counter via Button
        Given the counter starts at 5
        When we click the button to increase the counter
        Then the counter now has increased by one
    Scenario: Decrease Counter via Button
        Given the counter starts at 6
        When we click the button to decrease the counter
        Then the counter has now decreased by one

...and here's the Python. We're using the Firefox driver (gecko driver) for our testing, which I am passing into the step definitions via a properly configured environments.py file in our features/ directory.

from behave import given, when, then, step

@given('the counter page is not loaded')
def step_impl(context):
    context.driver.get("http://localhost:1234")
    assert "/counter" not in context.driver.current_url

@when('we click the counter navigation link')
def step_impl(context):
    link = context.driver.find_element_by_id("counterLink")
    context.actions.click(link).perform()

@then('the counter page is loaded')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "Counter:" in element.text

@then('the counter state has the correct default')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "5" in element.text

@given('the counter starts at 5')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "5" in element.text

@when('we click the button to increase the counter')
def step_impl(context):
    button = context.driver.find_element_by_id("incButton")
    context.actions.click(button).perform()

@then('the counter now has increased by one')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "6" in element.text

@given('the counter starts at 6')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "6" in element.text

@when('we click the button to decrease the counter')
def step_impl(context):
    button = context.driver.find_element_by_id("decButton")
    context.actions.click(button).perform()

@then('the counter has now decreased by one')
def step_impl(context):
    element = context.driver.find_element_by_id("counterText")
    assert "5" in element.text

The problem that I'm encountering is that the click event in the increase test is triggering twice, which then causes the decrease test to fail, as it's not starting at the expected value.

It appears as if the increase button test passes, then it clicks the button an extra time AFTER passing, then continues on. I'm not sure why this extra click is happening...

Any insight?

5
  • Have you tried to click without .perform? That is, context.actions.click(link) Commented Jun 21, 2019 at 3:00
  • Yeah, it requires .perform(), according to the docs. You build a "queue" of actions and then .perform() executes the queue. Commented Jun 21, 2019 at 3:12
  • I'll look more into this, though. Commented Jun 21, 2019 at 3:16
  • just try with button.click(). I don't see any logical issue in your script. Commented Jun 21, 2019 at 3:40
  • I actually didn't know you could call .click() directly on elements. The documentation I read didn't mention this functionality. If you write this as a solution instead of a comment, I'll definitely accept it! Thank you! Commented Jun 21, 2019 at 3:55

1 Answer 1

2

When you use actions which is webdriver.ActionChains you need first to move_to_element() in order to click it with ActionChains.

As an example:

my_element = context.driver.find_element_by_id("someid")
webdriver.ActionChains(context.driver).move_to_element(my_element).click(my_element).perform()

In your case as @supputuri mentioned in the comments, you don't need to use ActionChains rather use element.click() like this:

button = context.driver.find_element_by_id("decButton")
button.click()

Hope you find this helpful!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.