jnicklas / turnip

Gherkin extension for RSpec
974 stars 112 forks source link

Is it possible to access instance variables from custom placeholders #236

Open Tyflomate opened 3 years ago

Tyflomate commented 3 years ago

Hello ! I have a problem that is mentioned in #62 but this issue is pretty old so I decided to create a new one.

I would like to access an instance variable inside a place holder to do for example something like this:

placeholder :right do
    match /admin/ do
      @user.rights.find_by(admin: true)
    end

    match /visitor/ do
      @user.rights.find_by(visitor: true)
    end

    match /member/ do
      @user.rights.find_by(member: true)
    end
  end

@user is initialized in an other step file. For now, I tried implementing my steps outside a module but then @user was nil in my placeholder so I tried to move everything into the same module to counter this but now I have the error: undefined methodplaceholder' for #::Steps`.

So my question is: is it possible to access instance variables into placeholders ? How could I manage to make this work ?

Thanks a lot guys !

Tyflomate commented 3 years ago

@gongo, maybe you can help me out ? Thank you !

nitishr commented 3 years ago

I've been able to place a placeholder inside a module by including extend Turnip::DSL in the module. That might make the instance variable accessible in the placeholder as well, although I haven't tried that myself.

Tyflomate commented 3 years ago

Nice thanks for the comment ! I'll try that 👍

Tyflomate commented 3 years ago

Well i can now indeed put a custom placeholder into a module but instance variables are still nil inside it...

gongo commented 3 years ago

Hi @Tyflomate. Sorry for the late reply.

is it possible to access instance variables into placeholders ?

It impossible because placeholders are defined outside each step (module).

How could I manage to make this work ?

1️⃣ Declare with a global variable:

placeholder :right do
  match /admin/ do
    $user.rights.find_by(admin: true)
  end

  match /visitor/ do
    $user.rights.find_by(visitor: true)
  end

  match /member/ do
    $user.rights.find_by(member: true)
  end
end

2️⃣ Use steps_for

module Right
  step 'set user' do
    # examples..
    @user = {
      admin: 'admin',
      visitor: 'visitor',
      member: 'member',
    }
  end

  step 'displayed :name' do |name|
    @right.should eq(name)
  end
end

steps_for :admin do
  include Right

  step 'get right' do
    @right = @user[:admin]
  end
end

steps_for :visitor do
  include Right

  step 'get right' do
    @right = @user[:visitor]
  end
end
Feature: Steps for a feature
  Background:
    Given set user

  @admin
  Scenario: Admin
    Given get right
    Then displayed "admin"

  @visitor
  Scenario: Visitor
    Given get right
    Then displayed "visitor"