Commit 77103646 authored by Grzegorz Bizon's avatar Grzegorz Bizon Committed by Rémy Coutable

Make it possible to define global scenario attributes

parent 760b2c75
......@@ -4,4 +4,4 @@ require_relative '../qa'
QA::Scenario
.const_get(ARGV.shift)
.perform(*ARGV)
.launch!(*ARGV)
......@@ -18,6 +18,7 @@ module QA
##
# Support files
#
autoload :Bootable, 'qa/scenario/bootable'
autoload :Actable, 'qa/scenario/actable'
autoload :Entrypoint, 'qa/scenario/entrypoint'
autoload :Template, 'qa/scenario/template'
......
......@@ -3,7 +3,7 @@ module QA
module Mattermost
class Login < Page::Base
def initialize
visit(Runtime::Scenario.mattermost + '/login')
visit(Runtime::Scenario.mattermost_address + '/login')
end
def sign_in_using_oauth
......
......@@ -3,7 +3,7 @@ module QA
module Mattermost
class Main < Page::Base
def initialize
visit(Runtime::Scenario.mattermost)
visit(Runtime::Scenario.mattermost_address)
end
end
end
......
module QA
module Runtime
##
# Singleton approach to global test scenario arguments.
#
module Scenario
extend self
attr_accessor :mattermost
attr_reader :attributes
def define(attribute, value)
(@attributes ||= {}).store(attribute.to_sym, value)
define_singleton_method(attribute) do
@attributes[attribute.to_sym].tap do |value|
if value.to_s.empty?
raise ArgumentError, "Empty `#{attribute}` attribute!"
end
end
end
end
def method_missing(name, *)
raise ArgumentError, "Scenario attribute `#{name}` not defined!"
end
end
end
end
require 'optparse'
module QA
module Scenario
module Bootable
Option = Struct.new(:name, :arg, :desc)
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def launch!(argv)
arguments = OptionParser.new do |parser|
options.to_a.each do |opt|
parser.on(opt.arg, opt.desc) do |value|
Runtime::Scenario.define(opt.name, value)
end
end
end
arguments.parse!(argv)
if has_attributes?
self.perform(**Runtime::Scenario.attributes)
else
self.perform(*argv)
end
end
private
def attribute(name, arg, desc)
options.push(Option.new(name, arg, desc))
end
def options
@options ||= []
end
def has_attributes?
options.any?
end
end
end
end
end
......@@ -5,6 +5,8 @@ module QA
# including staging and on-premises installation.
#
class Entrypoint < Template
include Bootable
def self.tags(*tags)
@tags = tags
end
......
......@@ -10,7 +10,8 @@ module QA
tags :core, :mattermost
def perform(address, mattermost, *files)
Runtime::Scenario.mattermost = mattermost
Runtime::Scenario.define(:mattermost_address, mattermost)
super(address, *files)
end
end
......
describe QA::Runtime::Scenario do
subject do
Module.new.extend(described_class)
end
it 'makes it possible to define global scenario attributes' do
subject.define(:my_attribute, 'some-value')
subject.define(:another_attribute, 'another-value')
expect(subject.my_attribute).to eq 'some-value'
expect(subject.another_attribute).to eq 'another-value'
expect(subject.attributes)
.to eq(my_attribute: 'some-value', another_attribute: 'another-value')
end
it 'raises error when attribute is not known' do
expect { subject.invalid_accessor }
.to raise_error ArgumentError, /invalid_accessor/
end
it 'raises error when attribute is empty' do
subject.define(:empty_attribute, '')
expect { subject.empty_attribute }
.to raise_error ArgumentError, /empty_attribute/
end
end
describe QA::Scenario::Bootable do
subject do
Class.new(QA::Scenario::Template)
.include(described_class)
end
it 'makes it possible to define the scenario attribute' do
subject.class_eval do
attribute :something, '--something SOMETHING', 'Some attribute'
attribute :another, '--another ANOTHER', 'Some other attribute'
end
expect(subject).to receive(:perform)
.with(something: 'test', another: 'other')
subject.launch!(%w[--another other --something test])
end
it 'does not require attributes to be defined' do
expect(subject).to receive(:perform).with('some', 'argv')
subject.launch!(%w[some argv])
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment