0

Got this error when calling the webdriver object; this has been defined within a fixture. Please refer to the below details:

Code structure:

tests

features

design.feature

step_defs

__init__.py

conftest.py

test1.py

Code in design.feature:

Feature:
 As a user I want to do something...etc

Scenario: Create design
    Given the user log in to "Electric"
    When set the map area 52.21623,0.12519

Code in test1.py:

scenario('../features/design.feature', 'Create design')

def test_create_design():
    pass


@given(parsers.parse('the user log in to "{name}"'), target_fixture='browser')
def login(browser, name: str):
    browser.get(login_url)
    browser.maximize_window()
    username_box = WebDriverWait(browser, 10).until(
        EC.presence_of_element_located((By.ID, "login-user")))
    username_box.send_keys(username)
    password_box = WebDriverWait(browser, 10).until(
        EC.element_to_be_clickable((By.ID, "login-pass")))
    password_box.send_keys(password)
    elm = WebDriverWait(browser, 10).until(
        EC.element_to_be_clickable((By.ID, "login-submission")))
    elm.click()
    time.sleep(5)
    if name == 'Electric':
        elm = WebDriverWait(browser, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//*[@class='ui-layout-center ui-layout-pane ui-layout-pane-center']/"
                                                  "div[@id='app_options' ]/*[@class='box app_options_box'][2]")))
        elm.click()

    elif name == "Configuration":
        elm = WebDriverWait(browser, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, "//*[@class='ui-layout-center ui-layout-pane ui-layout-pane-center']/"
                           "div[@id='app_options' ]/*[@class='box app_options_box']"))
        )
        elm.click()
    time.sleep(5)
    


@when(parsers.parse('set the map area {lat},{long}'))
def set_map_area_and_center(browser, lat: float, long: float):

    print('you are here')
    time.sleep(5)
    browser.execute_script(f"myw.app.map.setView(myw.latLng({lat}, {long}))")
    time.sleep(3)
    browser.quit()

Code in conftest.py:

@pytest.fixture
def browser():
    w = webdriver.Chrome()
    yield w
    w.quit()

Result:

AttributeError: 'NoneType' object has no attribute 'execute_script' when function set_map_area_and_center is run--> at line browser.execute_script. This makes me think somehow the object is not returned from browser fixture? fixture browser is working when called first time in function login.

Expected result:

to be able to call the fixture within conftest.py or test1.py as many times is needed.

Can anybody help me understand why in the first instance(function login) fixture browser worked and second time (function set_map_area_and_center) didn't and how to solve this issue? Cheers.

Notes:

8
  • anybody, any idea is appreciated Commented Jul 16, 2022 at 20:48
  • Where is the @when decorator coming from? Commented Jul 16, 2022 at 21:19
  • Hi @Keith, I have updated the details about the code. "when" decorator comes from design.feature file and is inside the Scenario. Please refer to the above code. If you need any other info, please give me a shout. Commented Jul 16, 2022 at 23:20
  • It looks like the pytest fixture is going through a Selenium decorator. Is that correct? Commented Jul 16, 2022 at 23:40
  • Yes, basically decorators "given" and "when" are special pytest-bdd decorators in which steps from Scenario are defined. the weird thing is that in "given", when calling "browser" does not complain but second time, in "when", says basically that browser is of "None" type @Keith Commented Jul 17, 2022 at 7:48

1 Answer 1

0

at @given decorator, should not be target_fixture, this will "create" and use another fixture call browser-in my case and, second time when @when decorator wants to use the browser fixture, pytest will raise an error because, basically sees it created 2 times with the same name and does not recognize it, hence the "None" type. To work, instead of:

@given(parsers.parse('the user log in to "{name}"'), target_fixture='browser')
def login(browser, name: str):
    browser.get(login_url)

should be:

@given(parsers.parse('the user log in to "{name}"'))
def login(browser, name: str):
    browser.get(login_url)
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.