Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
51518019
Commit
51518019
authored
Oct 25, 2018
by
Lin Jen-Shin
Committed by
Douglas Barbosa Alexandre
Oct 25, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Always use `attribute` to define the product
parent
bf96ec85
Changes
34
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
540 additions
and
620 deletions
+540
-620
qa/qa.rb
qa/qa.rb
+0
-1
qa/qa/factory/README.md
qa/qa/factory/README.md
+170
-199
qa/qa/factory/base.rb
qa/qa/factory/base.rb
+57
-22
qa/qa/factory/dependency.rb
qa/qa/factory/dependency.rb
+0
-28
qa/qa/factory/product.rb
qa/qa/factory/product.rb
+9
-24
qa/qa/factory/repository/project_push.rb
qa/qa/factory/repository/project_push.rb
+6
-5
qa/qa/factory/repository/wiki_push.rb
qa/qa/factory/repository/wiki_push.rb
+6
-4
qa/qa/factory/resource/branch.rb
qa/qa/factory/resource/branch.rb
+5
-5
qa/qa/factory/resource/deploy_key.rb
qa/qa/factory/resource/deploy_key.rb
+11
-11
qa/qa/factory/resource/deploy_token.rb
qa/qa/factory/resource/deploy_token.rb
+11
-9
qa/qa/factory/resource/file.rb
qa/qa/factory/resource/file.rb
+5
-3
qa/qa/factory/resource/fork.rb
qa/qa/factory/resource/fork.rb
+16
-9
qa/qa/factory/resource/group.rb
qa/qa/factory/resource/group.rb
+4
-4
qa/qa/factory/resource/issue.rb
qa/qa/factory/resource/issue.rb
+8
-9
qa/qa/factory/resource/kubernetes_cluster.rb
qa/qa/factory/resource/kubernetes_cluster.rb
+8
-11
qa/qa/factory/resource/label.rb
qa/qa/factory/resource/label.rb
+8
-8
qa/qa/factory/resource/merge_request.rb
qa/qa/factory/resource/merge_request.rb
+25
-17
qa/qa/factory/resource/merge_request_from_fork.rb
qa/qa/factory/resource/merge_request_from_fork.rb
+13
-8
qa/qa/factory/resource/personal_access_token.rb
qa/qa/factory/resource/personal_access_token.rb
+4
-4
qa/qa/factory/resource/project.rb
qa/qa/factory/resource/project.rb
+14
-15
qa/qa/factory/resource/project_imported_from_github.rb
qa/qa/factory/resource/project_imported_from_github.rb
+5
-3
qa/qa/factory/resource/project_milestone.rb
qa/qa/factory/resource/project_milestone.rb
+8
-7
qa/qa/factory/resource/runner.rb
qa/qa/factory/resource/runner.rb
+6
-4
qa/qa/factory/resource/sandbox.rb
qa/qa/factory/resource/sandbox.rb
+3
-5
qa/qa/factory/resource/secret_variable.rb
qa/qa/factory/resource/secret_variable.rb
+6
-4
qa/qa/factory/resource/ssh_key.rb
qa/qa/factory/resource/ssh_key.rb
+5
-7
qa/qa/factory/resource/user.rb
qa/qa/factory/resource/user.rb
+5
-6
qa/qa/factory/resource/wiki.rb
qa/qa/factory/resource/wiki.rb
+5
-3
qa/qa/factory/settings/hashed_storage.rb
qa/qa/factory/settings/hashed_storage.rb
+4
-4
qa/qa/runtime/logger.rb
qa/qa/runtime/logger.rb
+1
-1
qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
...igure/auto_devops/create_project_with_auto_devops_spec.rb
+3
-1
qa/spec/factory/base_spec.rb
qa/spec/factory/base_spec.rb
+102
-41
qa/spec/factory/dependency_spec.rb
qa/spec/factory/dependency_spec.rb
+0
-79
qa/spec/factory/product_spec.rb
qa/spec/factory/product_spec.rb
+7
-59
No files found.
qa/qa.rb
View file @
51518019
...
...
@@ -39,7 +39,6 @@ module QA
module
Factory
autoload
:ApiFabricator
,
'qa/factory/api_fabricator'
autoload
:Base
,
'qa/factory/base'
autoload
:Dependency
,
'qa/factory/dependency'
autoload
:Product
,
'qa/factory/product'
module
Resource
...
...
qa/qa/factory/README.md
View file @
51518019
This diff is collapsed.
Click to expand it.
qa/qa/factory/base.rb
View file @
51518019
...
...
@@ -10,13 +10,42 @@ module QA
include
ApiFabricator
extend
Capybara
::
DSL
def_delegators
:evaluator
,
:dependency
,
:dependencies
def_delegators
:evaluator
,
:product
,
:attributes
NoValueError
=
Class
.
new
(
RuntimeError
)
def_delegators
:evaluator
,
:attribute
def
fabricate!
(
*
_args
)
raise
NotImplementedError
end
def
visit!
visit
(
web_url
)
end
private
def
populate_attribute
(
name
,
block
)
value
=
attribute_value
(
name
,
block
)
raise
NoValueError
,
"No value was computed for product
#{
name
}
of factory
#{
self
.
class
.
name
}
."
unless
value
value
end
def
attribute_value
(
name
,
block
)
api_value
=
api_resource
&
.
dig
(
name
)
if
api_value
&&
block
log_having_both_api_result_and_block
(
name
,
api_value
)
end
api_value
||
(
block
&&
instance_exec
(
&
block
))
end
def
log_having_both_api_result_and_block
(
name
,
api_value
)
QA
::
Runtime
::
Logger
.
info
"<
#{
self
.
class
}
> Attribute
#{
name
.
inspect
}
has both API response `
#{
api_value
}
` and a block. API response will be picked. Block will be ignored."
end
def
self
.
fabricate!
(
*
args
,
&
prepare_block
)
fabricate_via_api!
(
*
args
,
&
prepare_block
)
rescue
NotImplementedError
...
...
@@ -52,13 +81,10 @@ module QA
def
self
.
do_fabricate!
(
factory
:,
prepare_block
:,
parents:
[])
prepare_block
.
call
(
factory
)
if
prepare_block
dependencies
.
each
do
|
signature
|
Factory
::
Dependency
.
new
(
factory
,
signature
).
build!
(
parents:
parents
+
[
self
])
end
resource_web_url
=
yield
factory
.
web_url
=
resource_web_url
Factory
::
Product
.
populate!
(
factory
,
resource_web_url
)
Factory
::
Product
.
new
(
factory
)
end
private_class_method
:do_fabricate!
...
...
@@ -85,31 +111,40 @@ module QA
end
private_class_method
:evaluator
class
DSL
attr_reader
:dependencies
,
:attributes
def
self
.
dynamic_attributes
const_get
(
:DynamicAttributes
)
rescue
NameError
mod
=
const_set
(
:DynamicAttributes
,
Module
.
new
)
include
mod
mod
end
def
self
.
attributes_names
dynamic_attributes
.
instance_methods
(
false
).
sort
.
grep_v
(
/=$/
)
end
class
DSL
def
initialize
(
base
)
@base
=
base
@dependencies
=
[]
@attributes
=
[]
end
def
dependency
(
factory
,
as
:
,
&
block
)
as
.
tap
do
|
name
|
@base
.
class_eval
{
attr_accessor
name
}
def
attribute
(
name
,
&
block
)
@base
.
dynamic_attributes
.
module_eval
do
attr_writer
(
name
)
Dependency
::
Signature
.
new
(
name
,
factory
,
block
).
tap
do
|
signature
|
@dependencies
<<
signature
define_method
(
name
)
do
instance_variable_get
(
"@
#{
name
}
"
)
||
instance_variable_set
(
"@
#{
name
}
"
,
populate_attribute
(
name
,
block
))
end
end
end
def
product
(
attribute
,
&
block
)
Product
::
Attribute
.
new
(
attribute
,
block
).
tap
do
|
signature
|
@attributes
<<
signature
end
end
end
attribute
:web_url
end
end
end
qa/qa/factory/dependency.rb
deleted
100644 → 0
View file @
bf96ec85
module
QA
module
Factory
class
Dependency
Signature
=
Struct
.
new
(
:name
,
:factory
,
:block
)
def
initialize
(
caller_factory
,
dependency_signature
)
@caller_factory
=
caller_factory
@dependency_signature
=
dependency_signature
end
def
overridden?
!!
@caller_factory
.
public_send
(
@dependency_signature
.
name
)
end
def
build!
(
parents:
[])
return
if
overridden?
dependency
=
@dependency_signature
.
factory
.
fabricate!
(
parents:
parents
)
do
|
factory
|
@dependency_signature
.
block
&
.
call
(
factory
,
@caller_factory
)
end
dependency
.
tap
do
|
dependency
|
@caller_factory
.
public_send
(
"
#{
@dependency_signature
.
name
}
="
,
dependency
)
end
end
end
end
end
qa/qa/factory/product.rb
View file @
51518019
...
...
@@ -5,45 +5,30 @@ module QA
class
Product
include
Capybara
::
DSL
NoValueError
=
Class
.
new
(
RuntimeError
)
attr_reader
:factory
attr_reader
:factory
,
:web_url
Attribute
=
Struct
.
new
(
:name
,
:block
)
def
initialize
(
factory
,
web_url
)
def
initialize
(
factory
)
@factory
=
factory
@web_url
=
web_url
populate_attributes!
define_attributes
end
def
visit!
visit
(
web_url
)
end
def
self
.
populate!
(
factory
,
web_url
)
new
(
factory
,
web_url
)
def
populate
(
*
attributes
)
attributes
.
each
(
&
method
(
:public_send
)
)
end
private
def
populate_attributes!
factory
.
class
.
attributes
.
each
do
|
attribute
|
instance_exec
(
factory
,
attribute
.
block
)
do
|
factory
,
block
|
value
=
attribute_value
(
attribute
,
block
)
raise
NoValueError
,
"No value was computed for product
#{
attribute
.
name
}
of factory
#{
factory
.
class
.
name
}
."
unless
value
define_singleton_method
(
attribute
.
name
)
{
value
}
end
def
define_attributes
factory
.
class
.
attributes_names
.
each
do
|
name
|
define_singleton_method
(
name
)
do
factory
.
public_send
(
name
)
end
end
def
attribute_value
(
attribute
,
block
)
factory
.
api_resource
&
.
dig
(
attribute
.
name
)
||
(
block
&&
block
.
call
(
factory
))
||
(
factory
.
respond_to?
(
attribute
.
name
)
&&
factory
.
public_send
(
attribute
.
name
))
end
end
end
...
...
qa/qa/factory/repository/project_push.rb
View file @
51518019
...
...
@@ -2,13 +2,14 @@ module QA
module
Factory
module
Repository
class
ProjectPush
<
Factory
::
Repository
::
Push
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-code'
project
.
description
=
'Project with repository'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-code'
resource
.
description
=
'Project with repository'
end
end
product
:output
product
:project
attribute
:output
def
initialize
@file_name
=
'file.txt'
...
...
qa/qa/factory/repository/wiki_push.rb
View file @
51518019
...
...
@@ -2,10 +2,12 @@ module QA
module
Factory
module
Repository
class
WikiPush
<
Factory
::
Repository
::
Push
dependency
Factory
::
Resource
::
Wiki
,
as: :wiki
do
|
wiki
|
wiki
.
title
=
'Home'
wiki
.
content
=
'# My First Wiki Content'
wiki
.
message
=
'Update home'
attribute
:wiki
do
Factory
::
Resource
::
Wiki
.
fabricate!
do
|
resource
|
resource
.
title
=
'Home'
resource
.
content
=
'# My First Wiki Content'
resource
.
message
=
'Update home'
end
end
def
initialize
...
...
qa/qa/factory/resource/branch.rb
View file @
51518019
...
...
@@ -5,8 +5,10 @@ module QA
attr_accessor
:project
,
:branch_name
,
:allow_to_push
,
:allow_to_merge
,
:protected
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'protected-branch-project'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'protected-branch-project'
end
end
def
initialize
...
...
@@ -43,9 +45,7 @@ module QA
# to `allow_to_push` variable.
return
branch
unless
@protected
Page
::
Project
::
Menu
.
act
do
click_repository_settings
end
Page
::
Project
::
Menu
.
perform
(
&
:click_repository_settings
)
Page
::
Project
::
Settings
::
Repository
.
perform
do
|
setting
|
setting
.
expand_protected_branches
do
|
page
|
...
...
qa/qa/factory/resource/deploy_key.rb
View file @
51518019
...
...
@@ -4,11 +4,11 @@ module QA
class
DeployKey
<
Factory
::
Base
attr_accessor
:title
,
:key
product
:fingerprint
do
|
resource
|
Page
::
Project
::
Settings
::
Repository
.
act
do
expand_deploy_keys
do
|
key
|
key_offset
=
key
.
key_titles
.
index
do
|
title
|
title
.
text
==
resource
.
title
attribute
:fingerprint
do
Page
::
Project
::
Settings
::
Repository
.
perform
do
|
setting
|
setting
.
expand_deploy_keys
do
|
key
|
key_offset
=
key
.
key_titles
.
index
do
|
key_
title
|
key_title
.
text
==
title
end
key
.
key_fingerprints
[
key_offset
].
text
...
...
@@ -16,17 +16,17 @@ module QA
end
end
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-to-deploy'
project
.
description
=
'project for adding deploy key test'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-to-deploy'
resource
.
description
=
'project for adding deploy key test'
end
end
def
fabricate!
project
.
visit!
Page
::
Project
::
Menu
.
act
do
click_repository_settings
end
Page
::
Project
::
Menu
.
perform
(
&
:click_repository_settings
)
Page
::
Project
::
Settings
::
Repository
.
perform
do
|
setting
|
setting
.
expand_deploy_keys
do
|
page
|
...
...
qa/qa/factory/resource/deploy_token.rb
View file @
51518019
...
...
@@ -4,25 +4,27 @@ module QA
class
DeployToken
<
Factory
::
Base
attr_accessor
:name
,
:expires_at
product
:username
do
|
resource
|
Page
::
Project
::
Settings
::
Repository
.
act
do
expand_deploy_tokens
do
|
token
|
attribute
:username
do
Page
::
Project
::
Settings
::
Repository
.
perform
do
|
page
|
page
.
expand_deploy_tokens
do
|
token
|
token
.
token_username
end
end
end
product
:password
do
|
password
|
Page
::
Project
::
Settings
::
Repository
.
act
do
expand_deploy_tokens
do
|
token
|
attribute
:password
do
Page
::
Project
::
Settings
::
Repository
.
perform
do
|
page
|
page
.
expand_deploy_tokens
do
|
token
|
token
.
token_password
end
end
end
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-to-deploy'
project
.
description
=
'project for adding deploy token test'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-to-deploy'
resource
.
description
=
'project for adding deploy token test'
end
end
def
fabricate!
...
...
qa/qa/factory/resource/file.rb
View file @
51518019
...
...
@@ -8,8 +8,10 @@ module QA
:content
,
:commit_message
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-new-file'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-new-file'
end
end
def
initialize
...
...
@@ -21,7 +23,7 @@ module QA
def
fabricate!
project
.
visit!
Page
::
Project
::
Show
.
act
{
create_new_file!
}
Page
::
Project
::
Show
.
perform
(
&
:create_new_file!
)
Page
::
File
::
Form
.
perform
do
|
page
|
page
.
add_name
(
@name
)
...
...
qa/qa/factory/resource/fork.rb
View file @
51518019
...
...
@@ -2,16 +2,18 @@ module QA
module
Factory
module
Resource
class
Fork
<
Factory
::
Base
dependency
Factory
::
Repository
::
ProjectPush
,
as: :push
attribute
:push
do
Factory
::
Repository
::
ProjectPush
.
fabricate!
end
dependency
Factory
::
Resource
::
User
,
as: :user
do
|
user
|
attribute
:user
do
Factory
::
Resource
::
User
.
fabricate!
do
|
resource
|
if
Runtime
::
Env
.
forker?
user
.
username
=
Runtime
::
Env
.
forker_username
user
.
password
=
Runtime
::
Env
.
forker_password
resource
.
username
=
Runtime
::
Env
.
forker_username
resource
.
password
=
Runtime
::
Env
.
forker_password
end
end
end
product
:user
def
visit_project_with_retry
# The user intermittently fails to stay signed in after visiting the
...
...
@@ -48,15 +50,20 @@ module QA
end
def
fabricate!
push
user
visit_project_with_retry
Page
::
Project
::
Show
.
act
{
fork_project
}
Page
::
Project
::
Show
.
perform
(
&
:fork_project
)
Page
::
Project
::
Fork
::
New
.
perform
do
|
fork_new
|
fork_new
.
choose_namespace
(
user
.
name
)
end
Page
::
Layout
::
Banner
.
act
{
has_notice?
(
'The project was successfully forked.'
)
}
Page
::
Layout
::
Banner
.
perform
do
|
page
|
page
.
has_notice?
(
'The project was successfully forked.'
)
end
end
end
end
...
...
qa/qa/factory/resource/group.rb
View file @
51518019
...
...
@@ -4,12 +4,12 @@ module QA
class
Group
<
Factory
::
Base
attr_accessor
:path
,
:description
dependency
Factory
::
Resource
::
Sandbox
,
as: :sandbox
product
:id
do
true
# We don't retrieve the Group ID when using the Browser UI
attribute
:sandbox
do
Factory
::
Resource
::
Sandbox
.
fabricate!
end
attribute
:id
def
initialize
@path
=
Runtime
::
Namespace
.
name
@description
=
"QA test run at
#{
Runtime
::
Namespace
.
time
}
"
...
...
qa/qa/factory/resource/issue.rb
View file @
51518019
...
...
@@ -2,22 +2,21 @@ module QA
module
Factory
module
Resource
class
Issue
<
Factory
::
Base
attr_
accessor
:title
,
:description
,
:project
attr_
writer
:description
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-for-issues'
project
.
description
=
'project for adding issues'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-for-issues'
resource
.
description
=
'project for adding issues'
end
end
product
:project
product
:title
attribute
:title
def
fabricate!
project
.
visit!
Page
::
Project
::
Show
.
act
do
go_to_new_issue
end
Page
::
Project
::
Show
.
perform
(
&
:go_to_new_issue
)
Page
::
Project
::
Issue
::
New
.
perform
do
|
page
|
page
.
add_title
(
@title
)
...
...
qa/qa/factory/resource/kubernetes_cluster.rb
View file @
51518019
...
...
@@ -7,24 +7,21 @@ module QA
attr_writer
:project
,
:cluster
,
:install_helm_tiller
,
:install_ingress
,
:install_prometheus
,
:install_runner
product
:ingress_ip
do
Page
::
Project
::
Operations
::
Kubernetes
::
Show
.
perform
do
|
page
|
page
.
ingress_ip
end
attribute
:ingress_ip
do
Page
::
Project
::
Operations
::
Kubernetes
::
Show
.
perform
(
&
:ingress_ip
)
end
def
fabricate!
@project
.
visit!
Page
::
Project
::
Menu
.
act
{
click_operations_kubernetes
}
Page
::
Project
::
Menu
.
perform
(
&
:click_operations_kubernetes
)
Page
::
Project
::
Operations
::
Kubernetes
::
Index
.
perform
do
|
page
|
page
.
add_kubernetes_cluster
end
Page
::
Project
::
Operations
::
Kubernetes
::
Index
.
perform
(
&
:add_kubernetes_cluster
)
Page
::
Project
::
Operations
::
Kubernetes
::
Add
.
perform
do
|
page
|
page
.
add_existing_cluster
end
Page
::
Project
::
Operations
::
Kubernetes
::
Add
.
perform
(
&
:add_existing_cluster
)
Page
::
Project
::
Operations
::
Kubernetes
::
AddExisting
.
perform
do
|
page
|
page
.
set_cluster_name
(
@cluster
.
cluster_name
)
...
...
qa/qa/factory/resource/label.rb
View file @
51518019
...
...
@@ -4,14 +4,14 @@ module QA
module
Factory
module
Resource
class
Label
<
Factory
::
Base
attr_accessor
:title
,
:description
,
:color
attr_accessor
:description
,
:color
product
(
:title
)
{
|
factory
|
factory
.
title
}
attribute
:title
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-label'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-label'
end
end
def
initialize
...
...
@@ -23,8 +23,8 @@ module QA
def
fabricate!
project
.
visit!
Page
::
Project
::
Menu
.
act
{
go_to_labels
}
Page
::
Label
::
Index
.
act
{
go_to_new_label
}
Page
::
Project
::
Menu
.
perform
(
&
:go_to_labels
)
Page
::
Label
::
Index
.
perform
(
&
:go_to_new_label
)
Page
::
Label
::
New
.
perform
do
|
page
|
page
.
fill_title
(
@title
)
...
...
qa/qa/factory/resource/merge_request.rb
View file @
51518019
...
...
@@ -12,27 +12,33 @@ module QA
:milestone
,
:labels
product
:project
product
:source_branch
attribute
:source_branch
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-merge-request'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-merge-request'
end
end
attribute
:target
do
project
.
visit!
dependency
Factory
::
Repository
::
ProjectPush
,
as: :target
do
|
push
,
factory
|
factory
.
project
.
visit!
push
.
project
=
factory
.
project
push
.
branch_name
=
'master'
push
.
remote_branch
=
factory
.
target_branch
Factory
::
Repository
::
ProjectPush
.
fabricate!
do
|
resource
|
resource
.
project
=
project
resource
.
branch_name
=
'master'
resource
.
remote_branch
=
target_branch
end
end
dependency
Factory
::
Repository
::
ProjectPush
,
as: :source
do
|
push
,
factory
|
push
.
project
=
factory
.
project
push
.
branch_name
=
factory
.
target_branch
push
.
remote_branch
=
factory
.
source_branch
push
.
new_branch
=
false
push
.
file_name
=
"added_file.txt"
push
.
file_content
=
"File Added"
attribute
:source
do
Factory
::
Repository
::
ProjectPush
.
fabricate!
do
|
resource
|
resource
.
project
=
project
resource
.
branch_name
=
target_branch
resource
.
remote_branch
=
source_branch
resource
.
new_branch
=
false
resource
.
file_name
=
"added_file.txt"
resource
.
file_content
=
"File Added"
end
end
def
initialize
...
...
@@ -46,8 +52,10 @@ module QA
end
def
fabricate!
target
source
project
.
visit!
Page
::
Project
::
Show
.
act
{
new_merge_request
}
Page
::
Project
::
Show
.
perform
(
&
:new_merge_request
)
Page
::
MergeRequest
::
New
.
perform
do
|
page
|
page
.
fill_title
(
@title
)
page
.
fill_description
(
@description
)
...
...
qa/qa/factory/resource/merge_request_from_fork.rb
View file @
51518019
...
...
@@ -4,19 +4,24 @@ module QA
class
MergeRequestFromFork
<
MergeRequest
attr_accessor
:fork_branch
dependency
Factory
::
Resource
::
Fork
,
as: :fork
attribute
:fork
do
Factory
::
Resource
::
Fork
.
fabricate!
end
dependency
Factory
::
Repository
::
ProjectPush
,
as: :push
do
|
push
,
factory
|
push
.
project
=
factory
.
fork
push
.
branch_name
=
factory
.
fork_branch
push
.
file_name
=
'file2.txt'
push
.
user
=
factory
.
fork
.
user
attribute
:push
do
Factory
::
Repository
::
ProjectPush
.
fabricate!
do
|
resource
|
resource
.
project
=
fork
resource
.
branch_name
=
fork_branch
resource
.
file_name
=
'file2.txt'
resource
.
user
=
fork
.
user
end
end
def
fabricate!
push
fork
.
visit!
Page
::
Project
::
Show
.
act
{
new_merge_request
}
Page
::
MergeRequest
::
New
.
act
{
create_merge_request
}
Page
::
Project
::
Show
.
perform
(
&
:new_merge_request
)
Page
::
MergeRequest
::
New
.
perform
(
&
:create_merge_request
)
end
end
end
...
...
qa/qa/factory/resource/personal_access_token.rb
View file @
51518019
...
...
@@ -7,13 +7,13 @@ module QA
class
PersonalAccessToken
<
Factory
::
Base
attr_accessor
:name
product
:access_token
do
Page
::
Profile
::
PersonalAccessTokens
.
act
{
created_access_token
}
attribute
:access_token
do
Page
::
Profile
::
PersonalAccessTokens
.
perform
(
&
:created_access_token
)
end
def
fabricate!
Page
::
Main
::
Menu
.
act
{
go_to_profile_settings
}
Page
::
Profile
::
Menu
.
act
{
click_access_tokens
}
Page
::
Main
::
Menu
.
perform
(
&
:go_to_profile_settings
)
Page
::
Profile
::
Menu
.
perform
(
&
:click_access_tokens
)
Page
::
Profile
::
PersonalAccessTokens
.
perform
do
|
page
|
page
.
fill_token_name
(
name
||
'api-test-token'
)
...
...
qa/qa/factory/resource/project.rb
View file @
51518019
...
...
@@ -4,25 +4,24 @@ module QA
module
Factory
module
Resource
class
Project
<
Factory
::
Base
attr
_accessor
:description
attr
_reader
:name
attr
ibute
:name
attr
ibute
:description
dependency
Factory
::
Resource
::
Group
,
as: :group
product
:group
product
:name
attribute
:group
do
Factory
::
Resource
::
Group
.
fabricate!
end
product
:repository_ssh_location
do
Page
::
Project
::
Show
.
act
do
choose_repository_clone_ssh
repository_location
attribute
:repository_ssh_location
do
Page
::
Project
::
Show
.
perform
do
|
page
|
page
.
choose_repository_clone_ssh
page
.
repository_location
end
end
product
:repository_http_location
do
Page
::
Project
::
Show
.
act
do
choose_repository_clone_http
repository_location
attribute
:repository_http_location
do
Page
::
Project
::
Show
.
perform
do
|
page
|
page
.
choose_repository_clone_http
page
.
repository_location
end
end
...
...
@@ -37,7 +36,7 @@ module QA
def
fabricate!
group
.
visit!
Page
::
Group
::
Show
.
act
{
go_to_new_project
}
Page
::
Group
::
Show
.
perform
(
&
:go_to_new_project
)
Page
::
Project
::
New
.
perform
do
|
page
|
page
.
choose_test_namespace
...
...
qa/qa/factory/resource/project_imported_from_github.rb
View file @
51518019
...
...
@@ -6,14 +6,16 @@ module QA
class
ProjectImportedFromGithub
<
Resource
::
Project
attr_writer
:personal_access_token
,
:github_repository_path
dependency
Factory
::
Resource
::
Group
,
as: :group
attribute
:group
do
Factory
::
Resource
::
Group
.
fabricate!
end
product
:name
attribute
:name
def
fabricate!
group
.
visit!
Page
::
Group
::
Show
.
act
{
go_to_new_project
}
Page
::
Group
::
Show
.
perform
(
&
:go_to_new_project
)
Page
::
Project
::
New
.
perform
do
|
page
|
page
.
go_to_import_project
...
...
qa/qa/factory/resource/project_milestone.rb
View file @
51518019
...
...
@@ -3,11 +3,12 @@ module QA
module
Resource
class
ProjectMilestone
<
Factory
::
Base
attr_accessor
:description
attr_reader
:title
dependency
Factory
::
Resource
::
Project
,
as: :project
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
end
product
:title
attribute
:title
def
title
=
(
title
)
@title
=
"
#{
title
}
-
#{
SecureRandom
.
hex
(
4
)
}
"
...
...
@@ -17,12 +18,12 @@ module QA
def
fabricate!
project
.
visit!
Page
::
Project
::
Menu
.
act
do
click_issues
click_milestones
Page
::
Project
::
Menu
.
perform
do
|
page
|
page
.
click_issues
page
.
click_milestones
end
Page
::
Project
::
Milestone
::
Index
.
act
{
click_new_milestone
}
Page
::
Project
::
Milestone
::
Index
.
perform
(
&
:click_new_milestone
)
Page
::
Project
::
Milestone
::
New
.
perform
do
|
milestone_new
|
milestone_new
.
set_title
(
@title
)
...
...
qa/qa/factory/resource/runner.rb
View file @
51518019
...
...
@@ -6,9 +6,11 @@ module QA
class
Runner
<
Factory
::
Base
attr_writer
:name
,
:tags
,
:image
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-ci-cd'
project
.
description
=
'Project with CI/CD Pipelines'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-ci-cd'
resource
.
description
=
'Project with CI/CD Pipelines'
end
end
def
name
...
...
@@ -26,7 +28,7 @@ module QA
def
fabricate!
project
.
visit!
Page
::
Project
::
Menu
.
act
{
click_ci_cd_settings
}
Page
::
Project
::
Menu
.
perform
(
&
:click_ci_cd_settings
)
Service
::
Runner
.
new
(
name
).
tap
do
|
runner
|
Page
::
Project
::
Settings
::
CICD
.
perform
do
|
settings
|
...
...
qa/qa/factory/resource/sandbox.rb
View file @
51518019
...
...
@@ -8,17 +8,15 @@ module QA
class
Sandbox
<
Factory
::
Base
attr_reader
:path
product
:id
do
true
# We don't retrieve the Group ID when using the Browser UI
end
product
:path
attribute
:id
attribute
:path
def
initialize
@path
=
Runtime
::
Namespace
.
sandbox_name
end
def
fabricate!
Page
::
Main
::
Menu
.
act
{
go_to_groups
}
Page
::
Main
::
Menu
.
perform
(
&
:go_to_groups
)
Page
::
Dashboard
::
Groups
.
perform
do
|
page
|
if
page
.
has_group?
(
path
)
...
...
qa/qa/factory/resource/secret_variable.rb
View file @
51518019
...
...
@@ -4,15 +4,17 @@ module QA
class
SecretVariable
<
Factory
::
Base
attr_accessor
:key
,
:value
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-with-secret-variables'
project
.
description
=
'project for adding secret variable test'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-with-secret-variables'
resource
.
description
=
'project for adding secret variable test'
end
end
def
fabricate!
project
.
visit!
Page
::
Project
::
Menu
.
act
{
click_ci_cd_settings
}
Page
::
Project
::
Menu
.
perform
(
&
:click_ci_cd_settings
)
Page
::
Project
::
Settings
::
CICD
.
perform
do
|
setting
|
setting
.
expand_secret_variables
do
|
page
|
...
...
qa/qa/factory/resource/ssh_key.rb
View file @
51518019
...
...
@@ -6,21 +6,19 @@ module QA
class
SSHKey
<
Factory
::
Base
extend
Forwardable
attr_accessor
:title
attr_reader
:private_key
,
:public_key
,
:fingerprint
def_delegators
:key
,
:private_key
,
:public_key
,
:fingerprint
product
:private_key
product
:title
product
:fingerprint
attribute
:private_key
attribute
:title
attribute
:fingerprint
def
key
@key
||=
Runtime
::
Key
::
RSA
.
new
end
def
fabricate!
Page
::
Main
::
Menu
.
act
{
go_to_profile_settings
}
Page
::
Profile
::
Menu
.
act
{
click_ssh_keys
}
Page
::
Main
::
Menu
.
perform
(
&
:go_to_profile_settings
)
Page
::
Profile
::
Menu
.
perform
(
&
:click_ssh_keys
)
Page
::
Profile
::
SSHKeys
.
perform
do
|
page
|
page
.
add_key
(
public_key
,
title
)
...
...
qa/qa/factory/resource/user.rb
View file @
51518019
...
...
@@ -5,7 +5,6 @@ module QA
module
Resource
class
User
<
Factory
::
Base
attr_reader
:unique_id
attr_writer
:username
,
:password
,
:name
,
:email
def
initialize
@unique_id
=
SecureRandom
.
hex
(
8
)
...
...
@@ -31,14 +30,14 @@ module QA
defined?
(
@username
)
&&
defined?
(
@password
)
end
product
:name
product
:username
product
:email
product
:password
attribute
:name
attribute
:username
attribute
:email
attribute
:password
def
fabricate!
# Don't try to log-out if we're not logged-in
if
Page
::
Main
::
Menu
.
act
{
has_personal_area?
(
wait:
0
)
}
if
Page
::
Main
::
Menu
.
perform
{
|
p
|
p
.
has_personal_area?
(
wait:
0
)
}
Page
::
Main
::
Menu
.
perform
{
|
main
|
main
.
sign_out
}
end
...
...
qa/qa/factory/resource/wiki.rb
View file @
51518019
...
...
@@ -4,9 +4,11 @@ module QA
class
Wiki
<
Factory
::
Base
attr_accessor
:title
,
:content
,
:message
dependency
Factory
::
Resource
::
Project
,
as: :project
do
|
project
|
project
.
name
=
'project-for-wikis'
project
.
description
=
'project for adding wikis'
attribute
:project
do
Factory
::
Resource
::
Project
.
fabricate!
do
|
resource
|
resource
.
name
=
'project-for-wikis'
resource
.
description
=
'project for adding wikis'
end
end
def
fabricate!
...
...
qa/qa/factory/settings/hashed_storage.rb
View file @
51518019
...
...
@@ -5,9 +5,9 @@ module QA
def
fabricate!
(
*
traits
)
raise
ArgumentError
unless
traits
.
include?
(
:enabled
)
Page
::
Main
::
Login
.
act
{
sign_in_using_credentials
}
Page
::
Main
::
Menu
.
act
{
go_to_admin_area
}
Page
::
Admin
::
Menu
.
act
{
go_to_repository_settings
}
Page
::
Main
::
Login
.
perform
(
&
:sign_in_using_credentials
)
Page
::
Main
::
Menu
.
perform
(
&
:go_to_admin_area
)
Page
::
Admin
::
Menu
.
perform
(
&
:go_to_repository_settings
)
Page
::
Admin
::
Settings
::
Repository
.
perform
do
|
setting
|
setting
.
expand_repository_storage
do
|
page
|
...
...
@@ -16,7 +16,7 @@ module QA
end
end
QA
::
Page
::
Main
::
Menu
.
act
{
sign_out
}
QA
::
Page
::
Main
::
Menu
.
perform
(
&
:sign_out
)
end
end
end
...
...
qa/qa/runtime/logger.rb
View file @
51518019
...
...
@@ -7,7 +7,7 @@ module QA
module
Logger
extend
SingleForwardable
def_delegators
:logger
,
:debug
,
:info
,
:
error
,
:warn
,
:fatal
,
:unknown
def_delegators
:logger
,
:debug
,
:info
,
:
warn
,
:error
,
:fatal
,
:unknown
singleton_class
.
module_eval
do
def
logger
...
...
qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
View file @
51518019
...
...
@@ -49,11 +49,13 @@ module QA
cluster
.
install_prometheus
=
true
cluster
.
install_runner
=
true
end
kubernetes_cluster
.
populate
(
:ingress_ip
)
project
.
visit!
Page
::
Project
::
Menu
.
act
{
click_ci_cd_settings
}
Page
::
Project
::
Settings
::
CICD
.
perform
do
|
p
|
p
.
enable_auto_devops_with_domain
(
"
#{
kubernetes_cluster
.
ingress_ip
}
.nip.io"
)
p
.
enable_auto_devops_with_domain
(
"
#{
kubernetes_cluster
.
ingress_ip
}
.nip.io"
)
end
project
.
visit!
...
...
qa/spec/factory/base_spec.rb
View file @
51518019
...
...
@@ -19,7 +19,7 @@ describe QA::Factory::Base do
before
do
allow
(
subject
).
to
receive
(
:current_url
).
and_return
(
product_location
)
allow
(
subject
).
to
receive
(
:new
).
and_return
(
factory
)
allow
(
QA
::
Factory
::
Product
).
to
receive
(
:
populate!
).
with
(
factory
,
product_location
).
and_return
(
product
)
allow
(
QA
::
Factory
::
Product
).
to
receive
(
:
new
).
with
(
factory
).
and_return
(
product
)
end
end
...
...
@@ -115,73 +115,134 @@ describe QA::Factory::Base do
end
end
describe
'.dependency'
do
let
(
:dependency
)
{
spy
(
'dependency'
)
}
shared_context
'simple factory'
do
subject
do
Class
.
new
(
QA
::
Factory
::
Base
)
do
attribute
:test
do
'block'
end
before
do
stub_const
(
'Some::MyDependency'
,
dependency
)
attribute
:no_block
def
fabricate!
'any'
end
subject
do
Class
.
new
(
described_class
)
do
dependency
Some
::
MyDependency
,
as: :mydep
do
|
factory
|
factory
.
something!
def
self
.
current_url
'http://stub'
end
end
end
it
'appends a new dependency and accessors'
do
expect
(
subject
.
dependencies
).
to
be_one
let
(
:factory
)
{
subject
.
new
}
end
it
'defines dependency accessors'
do
expect
(
subject
.
new
).
to
respond_to
:mydep
,
:mydep
=
describe
'.attribute'
do
include_context
'simple factory'
it
'appends new product attribute'
do
expect
(
subject
.
attributes_names
).
to
eq
([
:no_block
,
:test
,
:web_url
])
end
describe
'dependencies fabrication
'
do
let
(
:dependency
)
{
double
(
'dependency'
)
}
let
(
:instance
)
{
spy
(
'instance'
)
}
context
'when the product attribute is populated via a block
'
do
it
'returns a fabrication product and defines factory attributes as its methods'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
subject
do
Class
.
new
(
described_class
)
do
dependency
Some
::
MyDependency
,
as: :mydep
expect
(
result
).
to
be_a
(
QA
::
Factory
::
Product
)
expect
(
result
.
test
).
to
eq
(
'block'
)
end
end
context
'when the product attribute is populated via the api'
do
let
(
:api_resource
)
{
{
no_block:
'api'
}
}
before
do
stub_const
(
'Some::MyDependency'
,
dependency
)
expect
(
factory
).
to
receive
(
:api_resource
).
and_return
(
api_resource
)
end
allow
(
subject
).
to
receive
(
:new
).
and_return
(
instance
)
allow
(
subject
).
to
receive
(
:current_url
).
and_return
(
product_location
)
allow
(
instance
).
to
receive
(
:mydep
).
and_return
(
nil
)
expect
(
QA
::
Factory
::
Product
).
to
receive
(
:populate!
)
it
'returns a fabrication product and defines factory attributes as its methods'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
expect
(
result
).
to
be_a
(
QA
::
Factory
::
Product
)
expect
(
result
.
no_block
).
to
eq
(
'api'
)
end
context
'when the attribute also has a block in the factory'
do
let
(
:api_resource
)
{
{
test:
'api_with_block'
}
}
before
do
allow
(
QA
::
Runtime
::
Logger
).
to
receive
(
:info
)
end
it
'builds all dependencies first
'
do
expect
(
dependency
).
to
receive
(
:fabricate!
).
once
it
'returns the api value and emits an INFO log entry
'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
subject
.
fabricate!
expect
(
result
).
to
be_a
(
QA
::
Factory
::
Product
)
expect
(
result
.
test
).
to
eq
(
'api_with_block'
)
expect
(
QA
::
Runtime
::
Logger
)
.
to
have_received
(
:info
).
with
(
/api_with_block/
)
end
end
end
describe
'.product'
do
include_context
'fabrication context'
context
'when the product attribute is populated via a factory attribute'
do
before
do
factory
.
test
=
'value'
end
subject
do
Class
.
new
(
described_class
)
do
def
fabricate!
"any"
it
'returns a fabrication product and defines factory attributes as its methods'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
expect
(
result
).
to
be_a
(
QA
::
Factory
::
Product
)
expect
(
result
.
test
).
to
eq
(
'value'
)
end
context
'when the api also has such response'
do
before
do
allow
(
factory
).
to
receive
(
:api_resource
).
and_return
({
test:
'api'
})
end
product
:token
it
'returns the factory attribute for the product'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
expect
(
result
).
to
be_a
(
QA
::
Factory
::
Product
)
expect
(
result
.
test
).
to
eq
(
'value'
)
end
end
end
it
'appends new product attribute'
do
expect
(
subject
.
attributes
).
to
be_one
expect
(
subject
.
attributes
[
0
]).
to
be_a
(
QA
::
Factory
::
Product
::
Attribute
)
expect
(
subject
.
attributes
[
0
].
name
).
to
eq
(
:token
)
context
'when the product attribute has no value'
do
it
'raises an error because no values could be found'
do
result
=
subject
.
fabricate!
(
factory:
factory
)
expect
{
result
.
no_block
}
.
to
raise_error
(
described_class
::
NoValueError
,
"No value was computed for product no_block of factory
#{
factory
.
class
.
name
}
."
)
end
end
end
describe
'#web_url'
do
include_context
'simple factory'
it
'sets #web_url to #current_url after fabrication'
do
subject
.
fabricate!
(
factory:
factory
)
expect
(
factory
.
web_url
).
to
eq
(
subject
.
current_url
)
end
end
describe
'#visit!'
do
include_context
'simple factory'
before
do
allow
(
factory
).
to
receive
(
:visit
)
end
it
'calls #visit with the underlying #web_url'
do
factory
.
web_url
=
subject
.
current_url
factory
.
visit!
expect
(
factory
).
to
have_received
(
:visit
).
with
(
subject
.
current_url
)
end
end
end
qa/spec/factory/dependency_spec.rb
deleted
100644 → 0
View file @
bf96ec85
describe
QA
::
Factory
::
Dependency
do
let
(
:dependency
)
{
spy
(
'dependency'
)
}
let
(
:factory
)
{
spy
(
'factory'
)
}
let
(
:block
)
{
spy
(
'block'
)
}
let
(
:signature
)
do
double
(
'signature'
,
name: :mydep
,
factory:
dependency
,
block:
block
)
end
subject
do
described_class
.
new
(
factory
,
signature
)
end
describe
'#overridden?'
do
it
'returns true if factory has overridden dependency'
do
allow
(
factory
).
to
receive
(
:mydep
).
and_return
(
'something'
)
expect
(
subject
).
to
be_overridden
end
it
'returns false if dependency has not been overridden'
do
allow
(
factory
).
to
receive
(
:mydep
).
and_return
(
nil
)
expect
(
subject
).
not_to
be_overridden
end
end
describe
'#build!'
do
context
'when dependency has been overridden'
do
before
do
allow
(
subject
).
to
receive
(
:overridden?
).
and_return
(
true
)
end
it
'does not fabricate dependency'
do
subject
.
build!
expect
(
dependency
).
not_to
have_received
(
:fabricate!
)
end
end
context
'when dependency has not been overridden'
do
before
do
allow
(
subject
).
to
receive
(
:overridden?
).
and_return
(
false
)
end
it
'fabricates dependency'
do
subject
.
build!
expect
(
dependency
).
to
have_received
(
:fabricate!
)
end
it
'sets product in the factory'
do
subject
.
build!
expect
(
factory
).
to
have_received
(
:mydep
=
).
with
(
dependency
)
end
it
'calls given block with dependency factory and caller factory'
do
expect
(
dependency
).
to
receive
(
:fabricate!
).
and_yield
(
dependency
)
subject
.
build!
expect
(
block
).
to
have_received
(
:call
).
with
(
dependency
,
factory
)
end
context
'with no block given'
do
let
(
:signature
)
do
double
(
'signature'
,
name: :mydep
,
factory:
dependency
,
block:
nil
)
end
it
'does not error'
do
subject
.
build!
expect
(
dependency
).
to
have_received
(
:fabricate!
)
end
end
end
end
end
qa/spec/factory/product_spec.rb
View file @
51518019
describe
QA
::
Factory
::
Product
do
let
(
:factory
)
do
Class
.
new
(
QA
::
Factory
::
Base
)
do
def
fo
o
'b
ar
'
attribute
:test
d
o
'b
lock
'
end
attribute
:no_block
end
.
new
end
let
(
:product
)
{
spy
(
'product'
)
}
let
(
:product_location
)
{
'http://product_location'
}
subject
{
described_class
.
new
(
factory
,
product_location
)
}
subject
{
described_class
.
new
(
factory
)
}
describe
'.populate!'
do
before
do
expect
(
factory
.
class
).
to
receive
(
:attributes
).
and_return
(
attributes
)
end
context
'when the product attribute is populated via a block'
do
let
(
:attributes
)
do
[
QA
::
Factory
::
Product
::
Attribute
.
new
(
:test
,
proc
{
'returned'
})]
end
it
'returns a fabrication product and defines factory attributes as its methods'
do
result
=
described_class
.
populate!
(
factory
,
product_location
)
expect
(
result
).
to
be_a
(
described_class
)
expect
(
result
.
test
).
to
eq
(
'returned'
)
end
end
context
'when the product attribute is populated via the api'
do
let
(
:attributes
)
do
[
QA
::
Factory
::
Product
::
Attribute
.
new
(
:test
)]
end
it
'returns a fabrication product and defines factory attributes as its methods'
do
expect
(
factory
).
to
receive
(
:api_resource
).
and_return
({
test:
'returned'
})
result
=
described_class
.
populate!
(
factory
,
product_location
)
expect
(
result
).
to
be_a
(
described_class
)
expect
(
result
.
test
).
to
eq
(
'returned'
)
end
end
context
'when the product attribute is populated via a factory attribute'
do
let
(
:attributes
)
do
[
QA
::
Factory
::
Product
::
Attribute
.
new
(
:foo
)]
end
it
'returns a fabrication product and defines factory attributes as its methods'
do
result
=
described_class
.
populate!
(
factory
,
product_location
)
expect
(
result
).
to
be_a
(
described_class
)
expect
(
result
.
foo
).
to
eq
(
'bar'
)
end
end
context
'when the product attribute has no value'
do
let
(
:attributes
)
do
[
QA
::
Factory
::
Product
::
Attribute
.
new
(
:bar
)]
end
it
'returns a fabrication product and defines factory attributes as its methods'
do
expect
{
described_class
.
populate!
(
factory
,
product_location
)
}
.
to
raise_error
(
described_class
::
NoValueError
,
"No value was computed for product bar of factory
#{
factory
.
class
.
name
}
."
)
end
end
factory
.
web_url
=
product_location
end
describe
'.visit!'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment