jeudi 20 juin 2019

Selenium (Python) + React

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?

Aucun commentaire:

Enregistrer un commentaire