module PageObjectStubs

Constants

DATE
VERSION

Public Class Methods

add_stubs_task(opts={}) click to toggle source

Adds stubs task to Rake

@param [Hash] opts @option opts [String] :task_name the name of the stubs task (optional) @option opts [String] :task_desc the description of the stubs task (optional) @option opts [lambda] :targets lambda that will return an array of targets (optional) @option opts [lambda] :output lambda that will return the output folder (optional)

# File lib/page_object_stubs/raketask.rb, line 11
def add_stubs_task opts={}
  task_name = opts.fetch(:task_name, 'stubs')
  task_desc = opts.fetch(:task_desc, 'Generate stubs')

  # Get the dir that contains the Rakefile via Rake (__dir__ will not work)
  targets   = opts.fetch(:targets, lambda { Dir.glob(File.join(Rake.application.original_dir, 'page', '*_page.rb')) })
  output    = opts.fetch(:output, lambda { File.join(Rake.application.original_dir, 'helper', 'stub') })
  exclude   = opts.fetch(:exclude, false)

  raise 'targets must be a lambda' unless targets.lambda?
  raise 'output must be a lambda' unless output.lambda?
  raise 'exclude must be a regex' if exclude && exclude.class != Regexp

  Rake.application.last_description = task_desc
  Rake::Task.define_task task_name do
    PageObjectStubs.generate targets: targets.call,
                             output:  output.call,
                             exclude: exclude
  end
end
generate(opts={}) click to toggle source

Creates stubs from target Ruby files in output folder with the format target_filename_stub.rb

Note the output folder is DELETED each time stubs are generated.

“‘ruby targets = Dir.glob(File.join(__dir__, ’..‘, ’page’, ‘*_page.rb’)) output = File.join(__dir__, ‘..’, ‘stub’) exclude = /#{Regexp.escape(‘base_page.rb’)}/ PageObjectStubs.generate targets: targets, output: output, exclude: exclude “‘

@param [Hash] opts @option opts [Array<File>] :targets Array of target files to create stubs from (required) @option opts [Dir] :output Folder to create stubs in (required) @option opts [Regexp] :exclude Exclusion regex use to reject targets (optional)

# File lib/page_object_stubs/page_object_stubs.rb, line 19
    def generate opts={}
      targets = opts.fetch(:targets)
      targets = targets.select do |target|
        File.file?(target) && File.readable?(target)
      end

      regex = opts.fetch(:exclude, false)
      targets.reject! { |t| t.match regex } if regex

      output_folder = File.expand_path(opts.fetch(:output))
      FileUtils.rm_rf output_folder
      FileUtils.mkdir_p output_folder

      targets.each do |f|
        ast          = Parser::CurrentRuby.parse File.read f
        page_objects = ProcessPageObjects.new

        page_objects.process ast

        file_name        = File.basename(f, '.*')
        file_module_name = file_name.split('_').map(&:capitalize).join
        file_method_name = file_name.downcase
        output_prefix    = <<R
module Stub
  module #{file_module_name}
    class << self
R
        data = ''

        def wrap method_name
          ' ' * 6 + "def #{method_name}; fail('stub called!'); end" + "\n"
        end

        page_objects.name_type_pairs.each do |pair|
          # process custom methods that aren't defined in page_object
          if pair.length == 1
            data += wrap "#{pair.first}(*args)"
            next
          end

          element_type = pair.first
          # if 'page_url' exists, then we need `def goto`
          # for all others, we need the name of the element to generate the remaining methods.
          if element_type == 'page_url'
            data += wrap 'goto'
            next
          end

          element_name = pair.last

          data += wrap "#{element_name}"
          data += wrap "#{element_name}_element"
          data += wrap "#{element_name}?"

          data += wrap "#{element_name}=" if element_type == 'text_field'
        end


        stub_file      = File.join(output_folder, file_name + '_stub.rb')

        # Note that the page method is defined as a singleton method on the
        # top level 'main' object. This ensures we're not polluting the global
        # object space by defining methods on every object which would happen
        # if Kernel was used instead.

        output_postfix = <<R
    end
  end
end

module RSpec
  module Core
    class ExampleGroup
      def #{file_method_name}
        Stub::#{file_module_name}
      end
    end
  end
end
R

        data = output_prefix + data + output_postfix

        File.open(stub_file, 'w') do |file|
          file.write data
        end
      end
    end
wrap(method_name) click to toggle source
# File lib/page_object_stubs/page_object_stubs.rb, line 48
def wrap method_name
  ' ' * 6 + "def #{method_name}; fail('stub called!'); end" + "\n"
end