summaryrefslogtreecommitdiff
path: root/qa
diff options
context:
space:
mode:
authorMatija Čupić <matteeyah@gmail.com>2018-02-04 23:38:59 +0100
committerMatija Čupić <matteeyah@gmail.com>2018-02-04 23:38:59 +0100
commit3366f377c1d4cbb02ecc5a2e47b059ed375c5e09 (patch)
tree6a19813b4820ad6d2813bf86b30d8e5be2bd10c6 /qa
parent0abce36cd20cdd3579138bee835d28519a5593f2 (diff)
parentcf887a8b3108edb715ee5618377f4ffab1824d85 (diff)
downloadgitlab-ce-3366f377c1d4cbb02ecc5a2e47b059ed375c5e09.tar.gz
Merge branch 'master' into 38265-stuckcijobsworker-wrongly-detects-cancels-stuck-builds-when-per-job-timeout-is-more-than-an-hour
Diffstat (limited to 'qa')
-rw-r--r--qa/README.md3
-rw-r--r--qa/qa.rb19
-rw-r--r--qa/qa/factory/dependency.rb7
-rw-r--r--qa/qa/factory/resource/issue.rb32
-rw-r--r--qa/qa/factory/resource/merge_request.rb49
-rw-r--r--qa/qa/page/admin/settings.rb13
-rw-r--r--qa/qa/page/base.rb41
-rw-r--r--qa/qa/page/component/dropzone.rb31
-rw-r--r--qa/qa/page/group/show.rb53
-rw-r--r--qa/qa/page/main/login.rb6
-rw-r--r--qa/qa/page/menu/admin.rb11
-rw-r--r--qa/qa/page/menu/side.rb8
-rw-r--r--qa/qa/page/merge_request/new.rb31
-rw-r--r--qa/qa/page/project/issue/index.rb17
-rw-r--r--qa/qa/page/project/issue/new.rb33
-rw-r--r--qa/qa/page/project/issue/show.rb40
-rw-r--r--qa/qa/page/project/new.rb4
-rw-r--r--qa/qa/page/project/settings/common.rb7
-rw-r--r--qa/qa/page/project/show.rb32
-rw-r--r--qa/qa/runtime/browser.rb2
-rw-r--r--qa/qa/specs/features/merge_request/create_spec.rb17
-rw-r--r--qa/qa/specs/features/project/create_issue_spec.rb18
-rw-r--r--qa/spec/factory/dependency_spec.rb13
-rw-r--r--qa/spec/fixtures/banana_sample.gifbin0 -> 71759 bytes
-rw-r--r--qa/spec/runtime/rsa_key.rb2
25 files changed, 435 insertions, 54 deletions
diff --git a/qa/README.md b/qa/README.md
index 3c1b61900d9..b937dc4c7a0 100644
--- a/qa/README.md
+++ b/qa/README.md
@@ -34,6 +34,9 @@ You can use GitLab QA to exercise tests on any live instance! For example, the
following call would login to a local [GDK] instance and run all specs in
`qa/specs/features`:
+First, `cd` into the `$gdk/gitlab/qa` directory.
+The `bin/qa` script expects you to be in the `qa` folder of the app.
+
```
bin/qa Test::Instance http://localhost:3000
```
diff --git a/qa/qa.rb b/qa/qa.rb
index e4e32de115f..8630e2a522c 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -27,7 +27,9 @@ module QA
module Resource
autoload :Sandbox, 'qa/factory/resource/sandbox'
autoload :Group, 'qa/factory/resource/group'
+ autoload :Issue, 'qa/factory/resource/issue'
autoload :Project, 'qa/factory/resource/project'
+ autoload :MergeRequest, 'qa/factory/resource/merge_request'
autoload :DeployKey, 'qa/factory/resource/deploy_key'
autoload :SecretVariable, 'qa/factory/resource/secret_variable'
autoload :Runner, 'qa/factory/resource/runner'
@@ -124,12 +126,22 @@ module QA
autoload :SecretVariables, 'qa/page/project/settings/secret_variables'
autoload :Runners, 'qa/page/project/settings/runners'
end
+
+ module Issue
+ autoload :New, 'qa/page/project/issue/new'
+ autoload :Show, 'qa/page/project/issue/show'
+ autoload :Index, 'qa/page/project/issue/index'
+ end
end
module Profile
autoload :PersonalAccessTokens, 'qa/page/profile/personal_access_tokens'
end
+ module MergeRequest
+ autoload :New, 'qa/page/merge_request/new'
+ end
+
module Admin
autoload :Settings, 'qa/page/admin/settings'
end
@@ -138,6 +150,13 @@ module QA
autoload :Main, 'qa/page/mattermost/main'
autoload :Login, 'qa/page/mattermost/login'
end
+
+ ##
+ # Classes describing components that are used by several pages.
+ #
+ module Component
+ autoload :Dropzone, 'qa/page/component/dropzone'
+ end
end
##
diff --git a/qa/qa/factory/dependency.rb b/qa/qa/factory/dependency.rb
index d0e85a68237..fc5dc82ce29 100644
--- a/qa/qa/factory/dependency.rb
+++ b/qa/qa/factory/dependency.rb
@@ -16,20 +16,21 @@ module QA
def build!
return if overridden?
- Builder.new(@signature).fabricate!.tap do |product|
+ Builder.new(@signature, @factory).fabricate!.tap do |product|
@factory.public_send("#{@name}=", product)
end
end
class Builder
- def initialize(signature)
+ def initialize(signature, caller_factory)
@factory = signature.factory
@block = signature.block
+ @caller_factory = caller_factory
end
def fabricate!
@factory.fabricate! do |factory|
- @block&.call(factory)
+ @block&.call(factory, @caller_factory)
end
end
end
diff --git a/qa/qa/factory/resource/issue.rb b/qa/qa/factory/resource/issue.rb
new file mode 100644
index 00000000000..95f48e20b3e
--- /dev/null
+++ b/qa/qa/factory/resource/issue.rb
@@ -0,0 +1,32 @@
+module QA
+ module Factory
+ module Resource
+ class Issue < Factory::Base
+ attr_writer :title, :description, :project
+
+ dependency Factory::Resource::Project, as: :project do |project|
+ project.name = 'project-for-issues'
+ project.description = 'project for adding issues'
+ end
+
+ product :title do
+ Page::Project::Issue::Show.act { issue_title }
+ end
+
+ def fabricate!
+ project.visit!
+
+ Page::Project::Show.act do
+ go_to_new_issue
+ end
+
+ Page::Project::Issue::New.perform do |page|
+ page.add_title(@title)
+ page.add_description(@description)
+ page.create_new_issue
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/factory/resource/merge_request.rb b/qa/qa/factory/resource/merge_request.rb
new file mode 100644
index 00000000000..ce04e904aaf
--- /dev/null
+++ b/qa/qa/factory/resource/merge_request.rb
@@ -0,0 +1,49 @@
+require 'securerandom'
+
+module QA
+ module Factory
+ module Resource
+ class MergeRequest < Factory::Base
+ attr_accessor :title,
+ :description,
+ :source_branch,
+ :target_branch
+
+ dependency Factory::Resource::Project, as: :project do |project|
+ project.name = 'project-with-merge-request'
+ end
+
+ dependency Factory::Repository::Push, as: :target do |push, factory|
+ push.project = factory.project
+ push.branch_name = "master:#{factory.target_branch}"
+ end
+
+ dependency Factory::Repository::Push, as: :source do |push, factory|
+ push.project = factory.project
+ push.branch_name = "#{factory.target_branch}:#{factory.source_branch}"
+ push.file_name = "added_file.txt"
+ push.file_content = "File Added"
+ end
+
+ def initialize
+ @title = 'QA test - merge request'
+ @description = 'This is a test merge request'
+ @source_branch = "qa-test-feature-#{SecureRandom.hex(8)}"
+ @target_branch = "master"
+ end
+
+ def fabricate!
+ project.visit!
+
+ Page::Project::Show.act { new_merge_request }
+
+ Page::MergeRequest::New.perform do |page|
+ page.fill_title(@title)
+ page.fill_description(@description)
+ page.create_merge_request
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/admin/settings.rb b/qa/qa/page/admin/settings.rb
index 1904732aee6..1f646103e7f 100644
--- a/qa/qa/page/admin/settings.rb
+++ b/qa/qa/page/admin/settings.rb
@@ -2,12 +2,13 @@ module QA
module Page
module Admin
class Settings < Page::Base
- ##
- # TODO, define all selectors required by this page object
- #
- # See gitlab-org/gitlab-qa#154
- #
- view 'app/views/admin/application_settings/show.html.haml'
+ view 'app/views/admin/application_settings/_form.html.haml' do
+ element :form_actions, '.form-actions'
+ element :submit, "submit 'Save'"
+ element :repository_storage, '%legend Repository Storage'
+ element :hashed_storage,
+ 'Create new projects using hashed storage paths'
+ end
def enable_hashed_storage
scroll_to 'legend', text: 'Repository Storage'
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 81ba80cdbaf..5c3af4b9115 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -13,16 +13,18 @@ module QA
visit current_url
end
- def wait(css = '.application', time: 60)
- Time.now.tap do |start|
- while Time.now - start < time
- break if page.has_css?(css, wait: 5)
+ def wait(max: 60, time: 1, reload: true)
+ start = Time.now
- refresh
- end
+ while Time.now - start < max
+ return true if yield
+
+ sleep(time)
+
+ refresh if reload
end
- yield if block_given?
+ false
end
def scroll_to(selector, text: nil)
@@ -40,14 +42,35 @@ module QA
page.within(selector) { yield } if block_given?
end
- def click_element(name)
- find_element(name).click
+ # Returns true if successfully GETs the given URL
+ # Useful because `page.status_code` is unsupported by our driver, and
+ # we don't have access to the `response` to use `have_http_status`.
+ def asset_exists?(url)
+ page.execute_script <<~JS
+ xhr = new XMLHttpRequest();
+ xhr.open('GET', '#{url}', true);
+ xhr.send();
+ JS
+
+ return false unless wait(time: 0.5, max: 60, reload: false) do
+ page.evaluate_script('xhr.readyState == XMLHttpRequest.DONE')
+ end
+
+ page.evaluate_script('xhr.status') == 200
end
def find_element(name)
find(element_selector_css(name))
end
+ def click_element(name)
+ find_element(name).click
+ end
+
+ def fill_element(name, content)
+ find_element(name).set(content)
+ end
+
def within_element(name)
page.within(element_selector_css(name)) do
yield
diff --git a/qa/qa/page/component/dropzone.rb b/qa/qa/page/component/dropzone.rb
new file mode 100644
index 00000000000..15bdc742fda
--- /dev/null
+++ b/qa/qa/page/component/dropzone.rb
@@ -0,0 +1,31 @@
+module QA
+ module Page
+ module Component
+ class Dropzone
+ attr_reader :page, :container
+
+ # page - A QA::Page::Base object
+ # container - CSS selector of the comment textarea's container
+ def initialize(page, container)
+ @page = page
+ @container = container
+ end
+
+ # Not tested and not expected to work with multiple dropzones
+ # instantiated on one page because there is no distinguishing
+ # attribute per dropzone file field.
+ def attach_file(attachment)
+ filename = File.basename(attachment)
+
+ field_style = { visibility: 'visible', height: '', width: '' }
+ page.attach_file(attachment, class: 'dz-hidden-input', make_visible: field_style)
+
+ # Wait for link to be appended to dropzone text
+ page.wait(reload: false) do
+ page.find("#{container} textarea").value.match(filename)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb
index 37ed3b35bce..d215518d316 100644
--- a/qa/qa/page/group/show.rb
+++ b/qa/qa/page/group/show.rb
@@ -2,12 +2,20 @@ module QA
module Page
module Group
class Show < Page::Base
- ##
- # TODO, define all selectors required by this page object
- #
- # See gitlab-org/gitlab-qa#154
- #
- view 'app/views/groups/show.html.haml'
+ view 'app/views/groups/show.html.haml' do
+ element :new_project_or_subgroup_dropdown, '.new-project-subgroup'
+ element :new_project_or_subgroup_dropdown_toggle, '.dropdown-toggle'
+ element :new_project_option, /%li.*data:.*value: "new-project"/
+ element :new_project_button, /%input.*data:.*action: "new-project"/
+ element :new_subgroup_option, /%li.*data:.*value: "new-subgroup"/
+
+ # data-value and data-action get modified by JS for subgroup
+ element :new_subgroup_button, /%input.*\.js-new-group-child/
+ end
+
+ view 'app/assets/javascripts/groups/constants.js' do
+ element :no_result_text, 'Sorry, no groups or projects matched your search'
+ end
def go_to_subgroup(name)
click_link name
@@ -20,26 +28,41 @@ module QA
def has_subgroup?(name)
filter_by_name(name)
- page.has_link?(name)
+ wait(reload: false) do
+ return false if page.has_content?('Sorry, no groups or projects matched your search')
+
+ page.has_link?(name)
+ end
end
def go_to_new_subgroup
- within '.new-project-subgroup' do
- find('.dropdown-toggle').click
- find("li[data-value='new-subgroup']").click
- end
+ click_new('subgroup')
find("input[data-action='new-subgroup']").click
end
def go_to_new_project
- within '.new-project-subgroup' do
- find('.dropdown-toggle').click
- find("li[data-value='new-project']").click
- end
+ click_new('project')
find("input[data-action='new-project']").click
end
+
+ private
+
+ def click_new(kind)
+ within '.new-project-subgroup' do
+ css = "li[data-value='new-#{kind}']"
+
+ # May need to click again because it is possible to click the button quicker than the JS is bound
+ wait(reload: false) do
+ find('.dropdown-toggle').click
+
+ page.has_css?(css)
+ end
+
+ find(css).click
+ end
+ end
end
end
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index 9cff2c5c317..95880475ffa 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -10,12 +10,14 @@ module QA
view 'app/views/devise/sessions/_new_base.html.haml' do
element :login_field, 'text_field :login'
- element :passowrd_field, 'password_field :password'
+ element :password_field, 'password_field :password'
element :sign_in_button, 'submit "Sign in"'
end
def initialize
- wait('.application', time: 500)
+ wait(max: 500) do
+ page.has_css?('.application')
+ end
end
def sign_in_using_credentials
diff --git a/qa/qa/page/menu/admin.rb b/qa/qa/page/menu/admin.rb
index 40da4a53e8a..573b98f7386 100644
--- a/qa/qa/page/menu/admin.rb
+++ b/qa/qa/page/menu/admin.rb
@@ -2,15 +2,8 @@ module QA
module Page
module Menu
class Admin < Page::Base
- ##
- # TODO, define all selectors required by this page object
- #
- # See gitlab-org/gitlab-qa#154
- #
- view 'app/views/admin/dashboard/index.html.haml'
-
- def go_to_license
- click_link 'License'
+ view 'app/views/layouts/nav/sidebar/_admin.html.haml' do
+ element :settings, "_('Settings')"
end
def go_to_settings
diff --git a/qa/qa/page/menu/side.rb b/qa/qa/page/menu/side.rb
index b2738152907..7e028add2ef 100644
--- a/qa/qa/page/menu/side.rb
+++ b/qa/qa/page/menu/side.rb
@@ -7,6 +7,8 @@ module QA
element :settings_link, 'link_to edit_project_path'
element :repository_link, "title: 'Repository'"
element :pipelines_settings_link, "title: 'CI / CD'"
+ element :issues_link, /link_to.*shortcuts-issues/
+ element :issues_link_text, "Issues"
element :top_level_items, '.sidebar-top-level-items'
element :activity_link, "title: 'Activity'"
end
@@ -43,6 +45,12 @@ module QA
end
end
+ def click_issues
+ within_sidebar do
+ click_link('Issues')
+ end
+ end
+
private
def hover_settings
diff --git a/qa/qa/page/merge_request/new.rb b/qa/qa/page/merge_request/new.rb
new file mode 100644
index 00000000000..ec94ff4ac98
--- /dev/null
+++ b/qa/qa/page/merge_request/new.rb
@@ -0,0 +1,31 @@
+module QA
+ module Page
+ module MergeRequest
+ class New < Page::Base
+ view 'app/views/shared/issuable/_form.html.haml' do
+ element :issuable_create_button
+ end
+
+ view 'app/views/shared/issuable/form/_title.html.haml' do
+ element :issuable_form_title
+ end
+
+ view 'app/views/shared/form_elements/_description.html.haml' do
+ element :issuable_form_description
+ end
+
+ def create_merge_request
+ click_element :issuable_create_button
+ end
+
+ def fill_title(title)
+ fill_element :issuable_form_title, title
+ end
+
+ def fill_description(description)
+ fill_element :issuable_form_description, description
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/issue/index.rb b/qa/qa/page/project/issue/index.rb
new file mode 100644
index 00000000000..b5903f536a4
--- /dev/null
+++ b/qa/qa/page/project/issue/index.rb
@@ -0,0 +1,17 @@
+module QA
+ module Page
+ module Project
+ module Issue
+ class Index < Page::Base
+ view 'app/views/projects/issues/_issue.html.haml' do
+ element :issue_link, 'link_to issue.title'
+ end
+
+ def go_to_issue(title)
+ click_link(title)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/issue/new.rb b/qa/qa/page/project/issue/new.rb
new file mode 100644
index 00000000000..7fc581da1ed
--- /dev/null
+++ b/qa/qa/page/project/issue/new.rb
@@ -0,0 +1,33 @@
+module QA
+ module Page
+ module Project
+ module Issue
+ class New < Page::Base
+ view 'app/views/shared/issuable/_form.html.haml' do
+ element :submit_issue_button, 'form.submit "Submit'
+ end
+
+ view 'app/views/shared/issuable/form/_title.html.haml' do
+ element :issue_title_textbox, 'form.text_field :title'
+ end
+
+ view 'app/views/shared/form_elements/_description.html.haml' do
+ element :issue_description_textarea, "render 'projects/zen', f: form, attr: :description"
+ end
+
+ def add_title(title)
+ fill_in 'issue_title', with: title
+ end
+
+ def add_description(description)
+ fill_in 'issue_description', with: description
+ end
+
+ def create_new_issue
+ click_on 'Submit issue'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
new file mode 100644
index 00000000000..5bc0598a524
--- /dev/null
+++ b/qa/qa/page/project/issue/show.rb
@@ -0,0 +1,40 @@
+module QA
+ module Page
+ module Project
+ module Issue
+ class Show < Page::Base
+ view 'app/views/projects/issues/show.html.haml' do
+ element :issue_details, '.issue-details'
+ element :title, '.title'
+ end
+
+ view 'app/views/shared/notes/_form.html.haml' do
+ element :new_note_form, 'new-note'
+ element :new_note_form, 'attr: :note'
+ end
+
+ view 'app/views/shared/notes/_comment_button.html.haml' do
+ element :comment_button, '%strong Comment'
+ end
+
+ def issue_title
+ find('.issue-details .title').text
+ end
+
+ # Adds a comment to an issue
+ # attachment option should be an absolute path
+ def comment(text, attachment: nil)
+ fill_in(with: text, name: 'note[note]')
+
+ unless attachment.nil?
+ QA::Page::Component::Dropzone.new(self, '.new-note')
+ .attach_file(attachment)
+ end
+
+ click_on 'Comment'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb
index 9b1438f76d5..186a4724326 100644
--- a/qa/qa/page/project/new.rb
+++ b/qa/qa/page/project/new.rb
@@ -4,7 +4,7 @@ module QA
class New < Page::Base
view 'app/views/projects/_new_project_fields.html.haml' do
element :project_namespace_select
- element :project_namespace_field, 'select :namespace_id'
+ element :project_namespace_field, /select :namespace_id.*class: 'select2/
element :project_path, 'text_field :path'
element :project_description, 'text_area :description'
element :project_create_button, "submit 'Create project'"
@@ -13,7 +13,7 @@ module QA
def choose_test_namespace
click_element :project_namespace_select
- first('li', text: Runtime::Namespace.path).click
+ find('ul.select2-result-sub > li', text: Runtime::Namespace.path).click
end
def choose_name(name)
diff --git a/qa/qa/page/project/settings/common.rb b/qa/qa/page/project/settings/common.rb
index c7955124ef3..319cb1045b6 100644
--- a/qa/qa/page/project/settings/common.rb
+++ b/qa/qa/page/project/settings/common.rb
@@ -17,7 +17,12 @@ module QA
def expand_section(name)
page.within('#content-body') do
page.within('section', text: name) do
- click_button 'Expand' unless first('button', text: 'Collapse')
+ # Because it is possible to click the button before the JS toggle code is bound
+ wait(reload: false) do
+ click_button 'Expand' unless first('button', text: 'Collapse')
+
+ page.has_content?('Collapse')
+ end
yield if block_given?
end
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index 5e66e40a0b5..553d35f9579 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -3,23 +3,35 @@ module QA
module Project
class Show < Page::Base
view 'app/views/shared/_clone_panel.html.haml' do
+ element :clone_holder, '.git-clone-holder'
element :clone_dropdown
element :clone_options_dropdown, '.clone-options-dropdown'
+ element :project_repository_location, 'text_field_tag :project_clone'
end
- view 'app/views/shared/_clone_panel.html.haml' do
- element :project_repository_location, 'text_field_tag :project_clone'
+ view 'app/views/projects/_last_push.html.haml' do
+ element :create_merge_request
end
view 'app/views/projects/_home_panel.html.haml' do
element :project_name
end
+ view 'app/views/layouts/header/_new_dropdown.haml' do
+ element :new_menu_toggle
+ element :new_issue_link, "link_to 'New issue', new_project_issue_path(@project)"
+ end
+
def choose_repository_clone_http
- click_element :clone_dropdown
+ wait(reload: false) do
+ click_element :clone_dropdown
+
+ page.within('.clone-options-dropdown') do
+ click_link('HTTP')
+ end
- page.within('.clone-options-dropdown') do
- click_link('HTTP')
+ # Ensure git clone textbox was updated to http URI
+ page.has_css?('.git-clone-holder input#project_clone[value*="http"]')
end
end
@@ -31,10 +43,20 @@ module QA
find('.qa-project-name').text
end
+ def new_merge_request
+ click_element :create_merge_request
+ end
+
def wait_for_push
sleep 5
refresh
end
+
+ def go_to_new_issue
+ click_element :new_menu_toggle
+
+ click_link 'New issue'
+ end
end
end
end
diff --git a/qa/qa/runtime/browser.rb b/qa/qa/runtime/browser.rb
index ce888b51ea5..a12d95683af 100644
--- a/qa/qa/runtime/browser.rb
+++ b/qa/qa/runtime/browser.rb
@@ -84,7 +84,7 @@ module QA
config.javascript_driver = :chrome
config.default_max_wait_time = 10
# https://github.com/mattheworiordan/capybara-screenshot/issues/164
- config.save_path = 'tmp'
+ config.save_path = File.expand_path('../../tmp', __dir__)
end
end
diff --git a/qa/qa/specs/features/merge_request/create_spec.rb b/qa/qa/specs/features/merge_request/create_spec.rb
new file mode 100644
index 00000000000..fbf9a4d17e5
--- /dev/null
+++ b/qa/qa/specs/features/merge_request/create_spec.rb
@@ -0,0 +1,17 @@
+module QA
+ feature 'creates a merge request', :core do
+ scenario 'user creates a new merge request' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Resource::MergeRequest.fabricate! do |merge_request|
+ merge_request.title = 'This is a merge request'
+ merge_request.description = 'Great feature'
+ end
+
+ expect(page).to have_content('This is a merge request')
+ expect(page).to have_content('Great feature')
+ expect(page).to have_content('Opened less than a minute ago')
+ end
+ end
+end
diff --git a/qa/qa/specs/features/project/create_issue_spec.rb b/qa/qa/specs/features/project/create_issue_spec.rb
new file mode 100644
index 00000000000..b73f108c2d9
--- /dev/null
+++ b/qa/qa/specs/features/project/create_issue_spec.rb
@@ -0,0 +1,18 @@
+module QA
+ feature 'creates issue', :core do
+ let(:issue_title) { 'issue title' }
+
+ scenario 'user creates issue' do
+ Runtime::Browser.visit(:gitlab, Page::Main::Login)
+ Page::Main::Login.act { sign_in_using_credentials }
+
+ Factory::Resource::Issue.fabricate! do |issue|
+ issue.title = issue_title
+ end
+
+ Page::Menu::Side.act { click_issues }
+
+ expect(page).to have_content(issue_title)
+ end
+ end
+end
diff --git a/qa/spec/factory/dependency_spec.rb b/qa/spec/factory/dependency_spec.rb
index 32405415126..8aaa6665a18 100644
--- a/qa/spec/factory/dependency_spec.rb
+++ b/qa/spec/factory/dependency_spec.rb
@@ -54,6 +54,19 @@ describe QA::Factory::Dependency do
expect(factory).to have_received(:mydep=).with(dependency)
end
+
+ context 'when receives a caller factory as block argument' do
+ let(:dependency) { QA::Factory::Base }
+
+ it 'calls given block with dependency factory and caller factory' do
+ allow_any_instance_of(QA::Factory::Base).to receive(:fabricate!).and_return(factory)
+ allow(QA::Factory::Product).to receive(:populate!).and_return(spy('any'))
+
+ subject.build!
+
+ expect(block).to have_received(:call).with(an_instance_of(QA::Factory::Base), factory)
+ end
+ end
end
end
end
diff --git a/qa/spec/fixtures/banana_sample.gif b/qa/spec/fixtures/banana_sample.gif
new file mode 100644
index 00000000000..1322ac92d14
--- /dev/null
+++ b/qa/spec/fixtures/banana_sample.gif
Binary files differ
diff --git a/qa/spec/runtime/rsa_key.rb b/qa/spec/runtime/rsa_key.rb
index ff277b9077b..6d7ab4dcd2e 100644
--- a/qa/spec/runtime/rsa_key.rb
+++ b/qa/spec/runtime/rsa_key.rb
@@ -3,7 +3,7 @@ describe QA::Runtime::RSAKey do
subject { described_class.new.public_key }
it 'generates a public RSA key' do
- expect(subject).to match(/\Assh\-rsa AAAA[0-9A-Za-z+\/]+={0,3}\z/)
+ expect(subject).to match(%r{\Assh\-rsa AAAA[0-9A-Za-z+/]+={0,3}\z})
end
end
end