From ddbb88010e05f6295dd6e46724d585494c8cc84a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 16 Jun 2017 22:07:14 -0700 Subject: Replace PhantomJS with headless Chrome for Rspec tests Closes #30876 --- .gitlab-ci.yml | 2 +- Gemfile | 2 +- Gemfile.lock | 18 ++++++++---------- features/support/capybara.rb | 22 +++++++++------------- scripts/prepare_build.sh | 3 +++ spec/support/capybara.rb | 23 ++++++++++------------- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0c266485b6..0f04df31e0a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-phantomjs-2.1-node-7.1-postgresql-9.6" +image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-59.0-node-7.1-postgresql-9.6" cache: key: "ruby-233-with-yarn" diff --git a/Gemfile b/Gemfile index 2c200f2fa7a..38599c1dabb 100644 --- a/Gemfile +++ b/Gemfile @@ -325,7 +325,7 @@ group :development, :test do gem 'capybara', '~> 2.6.2' gem 'capybara-screenshot', '~> 1.0.0' - gem 'poltergeist', '~> 1.9.0' + gem 'selenium-webdriver', '~> 2.53' gem 'spring', '~> 2.0.0' gem 'spring-commands-rspec', '~> 1.0.4' diff --git a/Gemfile.lock b/Gemfile.lock index 6755c75e331..b1d8b7356e5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -114,12 +114,13 @@ GEM mime-types (>= 1.16) cause (0.1) charlock_holmes (0.7.3) + childprocess (0.7.0) + ffi (~> 1.0, >= 1.0.11) chronic (0.10.2) chronic_duration (0.10.6) numerizer (~> 0.1.1) chunky_png (1.3.5) citrus (3.0.2) - cliver (0.3.2) coderay (1.1.1) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -584,11 +585,6 @@ GEM pg (0.18.4) po_to_json (1.0.1) json (>= 1.6.0) - poltergeist (1.9.0) - capybara (~> 2.1) - cliver (~> 0.3.1) - multi_json (~> 1.0) - websocket-driver (>= 0.2.0) posix-spawn (0.3.11) powerpack (0.1.1) premailer (1.8.6) @@ -769,6 +765,10 @@ GEM activesupport (>= 3.1) select2-rails (3.5.9.3) thor (~> 0.14) + selenium-webdriver (2.53.4) + childprocess (~> 0.5) + rubyzip (~> 1.0) + websocket (~> 1.0) sentry-raven (2.4.0) faraday (>= 0.7.6, < 1.0) settingslogic (2.0.9) @@ -891,9 +891,7 @@ GEM hashdiff webpack-rails (0.9.10) railties (>= 3.2.0) - websocket-driver (0.6.3) - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.2) + websocket (1.2.4) wikicloth (0.8.1) builder expression_parser @@ -1042,7 +1040,6 @@ DEPENDENCIES peek-redis (~> 1.2.0) peek-sidekiq (~> 1.0.3) pg (~> 0.18.2) - poltergeist (~> 1.9.0) premailer-rails (~> 1.9.0) prometheus-client-mmap (~> 0.7.0.beta5) pry-byebug (~> 3.4.1) @@ -1081,6 +1078,7 @@ DEPENDENCIES scss_lint (~> 0.47.0) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) + selenium-webdriver (~> 2.53) sentry-raven (~> 2.4.0) settingslogic (~> 2.0.9) sham_rack (~> 1.3.6) diff --git a/features/support/capybara.rb b/features/support/capybara.rb index f4691647d4b..1d1626a064b 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -1,22 +1,18 @@ -require 'capybara/poltergeist' require 'capybara-screenshot/spinach' # Give CI some extra time timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 -Capybara.javascript_driver = :poltergeist -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new( - app, - js_errors: true, - timeout: timeout, - window_size: [1366, 768], - url_whitelist: %w[localhost 127.0.0.1], - url_blacklist: %w[.mp4 .png .gif .avi .bmp .jpg .jpeg], - phantomjs_options: [ - '--load-images=yes' - ] +Capybara.javascript_driver = :chrome +Capybara.register_driver :chrome do |app| + capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( + 'chromeOptions' => { + 'args' => %w[headless no-sandbox disable-gpu] + } ) + + Capybara::Selenium::Driver + .new(app, browser: :chrome, desired_capabilities: capabilities) end Capybara.default_max_wait_time = timeout diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 03de59f27ad..07bbf901ad0 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -1,5 +1,8 @@ . scripts/utils.sh +wget -q https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip +unzip chromedriver_linux64.zip -d /usr/local/bin + export SETUP_DB=${SETUP_DB:-true} export USE_BUNDLE_INSTALL=${USE_BUNDLE_INSTALL:-true} export BUNDLE_INSTALL_FLAGS="--without production --jobs $(nproc) --path vendor --retry 3 --quiet" diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 4aa81a03558..fbe8ae30565 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -1,25 +1,22 @@ # rubocop:disable Style/GlobalVars require 'capybara/rails' require 'capybara/rspec' -require 'capybara/poltergeist' require 'capybara-screenshot/rspec' +require 'selenium-webdriver' # Give CI some extra time timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 -Capybara.javascript_driver = :poltergeist -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new( - app, - js_errors: true, - timeout: timeout, - window_size: [1366, 768], - url_whitelist: %w[localhost 127.0.0.1], - url_blacklist: %w[.mp4 .png .gif .avi .bmp .jpg .jpeg], - phantomjs_options: [ - '--load-images=yes' - ] +Capybara.javascript_driver = :chrome +Capybara.register_driver :chrome do |app| + capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( + 'chromeOptions' => { + 'args' => %w[headless no-sandbox disable-gpu] + } ) + + Capybara::Selenium::Driver + .new(app, browser: :chrome, desired_capabilities: capabilities) end Capybara.default_max_wait_time = timeout -- cgit v1.2.1 From bece18aa592f3b93c1a697310dc1ee6d943fde25 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 16 Jun 2017 22:35:46 -0700 Subject: Make Capybara::Screenshot work with headless Chrome --- features/support/capybara.rb | 4 ++++ spec/support/capybara.rb | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 1d1626a064b..595577804bd 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -20,6 +20,10 @@ Capybara.ignore_hidden_elements = false # Keep only the screenshots generated from the last failing test suite Capybara::Screenshot.prune_strategy = :keep_last_run +# From https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326 +Capybara::Screenshot.register_driver(:chrome) do |driver, path| + driver.browser.save_screenshot(path) +end Spinach.hooks.before_run do TestEnv.eager_load_driver_server diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index fbe8ae30565..4a4b037d0b1 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -24,6 +24,10 @@ Capybara.ignore_hidden_elements = true # Keep only the screenshots generated from the last failing test suite Capybara::Screenshot.prune_strategy = :keep_last_run +# From https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326 +Capybara::Screenshot.register_driver(:chrome) do |driver, path| + driver.browser.save_screenshot(path) +end RSpec.configure do |config| config.before(:context, :js) do -- cgit v1.2.1 From 5854ab2f7da76804a3221d962979cab67aef65c4 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 16 Jun 2017 23:08:27 -0700 Subject: Convert variants of trigger('click') -> click --- features/steps/dashboard/dashboard.rb | 2 +- features/steps/dashboard/todos.rb | 6 +++--- features/steps/profile/notifications.rb | 2 +- features/steps/project/merge_requests.rb | 12 ++++++------ features/steps/search.rb | 8 ++++---- features/steps/shared/diff_note.rb | 6 +++--- spec/features/boards/sidebar_spec.rb | 4 ++-- spec/features/dashboard/active_tab_spec.rb | 2 +- spec/features/dashboard/group_spec.rb | 2 +- spec/features/dashboard/groups_list_spec.rb | 6 +++--- spec/features/dashboard/issues_spec.rb | 2 +- spec/features/dashboard/merge_requests_spec.rb | 2 +- spec/features/explore/new_menu_spec.rb | 10 +++++----- spec/features/issues/filtered_search/recent_searches_spec.rb | 4 ++-- spec/features/issues/issue_sidebar_spec.rb | 2 +- spec/features/issues_spec.rb | 2 +- spec/features/merge_requests/conflicts_spec.rb | 2 +- spec/features/merge_requests/diff_notes_avatars_spec.rb | 2 +- spec/features/merge_requests/diff_notes_resolve_spec.rb | 2 +- spec/features/merge_requests/mini_pipeline_graph_spec.rb | 2 +- spec/features/merge_requests/user_posts_diff_notes_spec.rb | 4 ++-- spec/features/merge_requests/versions_spec.rb | 4 ++-- spec/features/profiles/preferences_spec.rb | 2 +- spec/features/projects/branches_spec.rb | 4 ++-- spec/features/projects/group_links_spec.rb | 2 +- spec/features/projects/jobs_spec.rb | 2 +- spec/features/projects/pipelines/pipeline_spec.rb | 12 ++++++------ spec/features/projects/pipelines/pipelines_spec.rb | 12 ++++++------ spec/features/projects/services/jira_service_spec.rb | 2 +- spec/features/projects/wiki/markdown_preview_spec.rb | 6 +++--- spec/features/projects/wiki/user_creates_wiki_page_spec.rb | 2 +- spec/features/protected_branches_spec.rb | 2 +- spec/features/search_spec.rb | 8 ++++---- spec/features/tags/master_creates_tag_spec.rb | 2 +- spec/features/todos/todos_spec.rb | 6 +++--- spec/features/user_callout_spec.rb | 2 +- spec/support/features/discussion_comments_shared_example.rb | 4 ++-- .../protected_branches/access_control_ce_shared_examples.rb | 2 +- .../protected_tags/access_control_ce_shared_examples.rb | 2 +- spec/support/quick_actions_helpers.rb | 2 +- spec/support/time_tracking_shared_examples.rb | 2 +- 41 files changed, 82 insertions(+), 82 deletions(-) diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 71c69a4fdea..e221a550882 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -22,7 +22,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I click "Create merge request" link' do - find_link("Create merge request", visible: false).trigger('click') + find_link("Create merge request", visible: false).click end step 'I see prefilled new Merge Request page' do diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb index 4a33babe3bd..0b4a69b2a91 100644 --- a/features/steps/dashboard/todos.rb +++ b/features/steps/dashboard/todos.rb @@ -55,7 +55,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps merge_request_reference = merge_request.to_reference(full: true) issue_reference = issue.to_reference(full: true) - find('.js-todos-mark-all').trigger('click') + find('.js-todos-mark-all').click page.within('.todos-count') { expect(page).to have_content '0' } expect(page).to have_content 'To do 0' @@ -69,7 +69,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps end step 'I should see the todo marked as done' do - find('.todos-done a').trigger('click') + find('.todos-done a').click expect(page).to have_link project.name_with_namespace should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_irreversible) @@ -79,7 +79,7 @@ class Spinach::Features::DashboardTodos < Spinach::FeatureSteps merge_request_reference = merge_request.to_reference(full: true) issue_reference = issue.to_reference(full: true) - find('.todos-done a').trigger('click') + find('.todos-done a').click expect(page).to have_link project.name_with_namespace should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, state: :done_irreversible) diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb index 7e339443b75..f8eb0f01de8 100644 --- a/features/steps/profile/notifications.rb +++ b/features/steps/profile/notifications.rb @@ -11,7 +11,7 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps end step 'I select Mention setting from dropdown' do - first(:link, "On mention").trigger('click') + first(:link, "On mention").click end step 'I should see Notification saved message' do diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 69f5d0f8410..54d7475f8da 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -34,7 +34,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click link "Merged"' do - find('#state-merged').trigger('click') + find('#state-merged').click end step 'I click link "Closed"' do @@ -336,7 +336,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I click on the Discussion tab' do page.within '.merge-request-tabs' do - find('.notes-tab').trigger('click') + find('.notes-tab').click end # Waits for load @@ -420,7 +420,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click link "Reopen"' do - first(:css, '.reopen-mr-link').trigger('click') + first(:css, '.reopen-mr-link').click end step 'I should see reopened merge request "Bug NS-04"' do @@ -432,13 +432,13 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I click link "Hide inline discussion" of the third file' do page.within '.files>div:nth-child(3)' do - find('.js-toggle-diff-comments').trigger('click') + find('.js-toggle-diff-comments').click end end step 'I click link "Show inline discussion" of the third file' do page.within '.files>div:nth-child(3)' do - find('.js-toggle-diff-comments').trigger('click') + find('.js-toggle-diff-comments').click end end @@ -510,7 +510,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click Side-by-side Diff tab' do - find('a', text: 'Side-by-side').trigger('click') + find('a', text: 'Side-by-side').click # Waits for load expect(page).to have_css('.parallel') diff --git a/features/steps/search.rb b/features/steps/search.rb index 16c4a5ab2e4..2f1b8cc0156 100644 --- a/features/steps/search.rb +++ b/features/steps/search.rb @@ -10,12 +10,12 @@ class Spinach::Features::Search < Spinach::FeatureSteps step 'I search for "Foo"' do fill_in "dashboard_search", with: "Foo" - find('.btn-search').trigger('click') + find('.btn-search').click end step 'I search for "rspec"' do fill_in "dashboard_search", with: "rspec" - find('.btn-search').trigger('click') + find('.btn-search').click end step 'I search for "rspec" on project page' do @@ -25,7 +25,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps step 'I search for "Wiki content"' do fill_in "dashboard_search", with: "content" - find('.btn-search').trigger('click') + find('.btn-search').click end step 'I click "Issues" link' do @@ -35,7 +35,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps end step 'I click project "Shop" link' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within '.project-filter' do click_link project.name_with_namespace end diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index 36fc315599e..5c6a4fbc6d4 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -215,7 +215,7 @@ module SharedDiffNote end step 'I click side-by-side diff button' do - find('#parallel-diff-btn').trigger('click') + find('#parallel-diff-btn').click end step 'I see side-by-side diff button' do @@ -228,11 +228,11 @@ module SharedDiffNote def click_diff_line(code) find(".line_holder[id='#{code}'] td:nth-of-type(1)").trigger 'mouseover' - find(".line_holder[id='#{code}'] button").trigger 'click' + find(".line_holder[id='#{code}'] button").click end def click_parallel_diff_line(code, line_type) find(".line_content.parallel.#{line_type}[data-line-code='#{code}']").trigger 'mouseover' - find(".line_holder.parallel button[data-line-code='#{code}']").trigger 'click' + find(".line_holder.parallel button[data-line-code='#{code}']").click end end diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 235e4899707..03b15bef41e 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -51,7 +51,7 @@ describe 'Issue Boards', feature: true, js: true do expect(page).to have_selector('.issue-boards-sidebar') - find('.gutter-toggle').trigger('click') + find('.gutter-toggle').click expect(page).not_to have_selector('.issue-boards-sidebar') end @@ -155,7 +155,7 @@ describe 'Issue Boards', feature: true, js: true do end page.within(find('.board:nth-child(2)')) do - find('.card:nth-child(2)').trigger('click') + find('.card:nth-child(2)').click end page.within('.assignee') do diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb index ae750be4d4a..f4ff9e6813f 100644 --- a/spec/features/dashboard/active_tab_spec.rb +++ b/spec/features/dashboard/active_tab_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Active Tab', js: true, feature: true do shared_examples 'page has active tab' do |title| it "#{title} tab" do - find('.global-dropdown-toggle').trigger('click') + find('.global-dropdown-toggle').click expect(page).to have_selector('.global-dropdown-menu li.active', count: 1) expect(find('.global-dropdown-menu li.active')).to have_content(title) end diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb index 8e20fdec8ad..78b9da08a36 100644 --- a/spec/features/dashboard/group_spec.rb +++ b/spec/features/dashboard/group_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Group', feature: true do it 'creates new group', js: true do visit dashboard_groups_path - find('.btn-new').trigger('click') + find('.btn-new').click new_path = 'Samurai' new_description = 'Tokugawa Shogunate' diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index 7eb254f8451..5eb56be6c7c 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -74,14 +74,14 @@ describe 'Dashboard Groups page', js: true, feature: true do expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right") # Collapse - find("#group-#{group.id}").trigger('click') + find("#group-#{group.id}").click expect(page).not_to have_selector("#group-#{group.id} .fa-caret-down") expect(page).to have_selector("#group-#{group.id} .fa-caret-right", count: 1) expect(page).not_to have_selector("#group-#{group.id} #group-#{subgroup.id}") # Expand - find("#group-#{group.id}").trigger('click') + find("#group-#{group.id}").click expect(page).to have_selector("#group-#{group.id} .fa-caret-down", count: 1) expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right") @@ -115,7 +115,7 @@ describe 'Dashboard Groups page', js: true, feature: true do expect(page).not_to have_selector("#group-#{group.id}") # Go to next page - find(".gl-pagination .page:not(.active) a").trigger('click') + find(".gl-pagination .page:not(.active) a").click wait_for_requests diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 2cea6b1563e..5fb74e0d007 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -65,7 +65,7 @@ RSpec.describe 'Dashboard Issues', feature: true do describe 'new issue dropdown' do it 'shows projects only with issues feature enabled', js: true do - find('.new-project-item-select-button').trigger('click') + find('.new-project-item-select-button').click page.within('.select2-results') do expect(page).to have_content(project.name_with_namespace) diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index bcb52f602b0..3cec2192910 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -17,7 +17,7 @@ describe 'Dashboard Merge Requests' do end it 'shows projects only with merge requests feature enabled', js: true do - find('.new-project-item-select-button').trigger('click') + find('.new-project-item-select-button').click page.within('.select2-results') do expect(page).to have_content(project.name_with_namespace) diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb index 15a6354211b..b1dbf48b221 100644 --- a/spec/features/explore/new_menu_spec.rb +++ b/spec/features/explore/new_menu_spec.rb @@ -69,9 +69,9 @@ feature 'Top Plus Menu', feature: true, js: true do visit namespace_project_path(project.namespace, project) page.within '.header-content' do - find('.header-new-dropdown-toggle').trigger('click') + find('.header-new-dropdown-toggle').click expect(page).to have_selector('.header-new.dropdown.open', count: 1) - find('.header-new-project-snippet a').trigger('click') + find('.header-new-project-snippet a').click end expect(page).to have_content('New Snippet') @@ -91,9 +91,9 @@ feature 'Top Plus Menu', feature: true, js: true do visit group_path(group) page.within '.header-content' do - find('.header-new-dropdown-toggle').trigger('click') + find('.header-new-dropdown-toggle').click expect(page).to have_selector('.header-new.dropdown.open', count: 1) - find('.header-new-group-project a').trigger('click') + find('.header-new-group-project a').click end expect(page).to have_content('Project path') @@ -160,7 +160,7 @@ feature 'Top Plus Menu', feature: true, js: true do def click_topmenuitem(item_name) page.within '.header-content' do - find('.header-new-dropdown-toggle').trigger('click') + find('.header-new-dropdown-toggle').click expect(page).to have_selector('.header-new.dropdown.open', count: 1) click_link item_name end diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index 09f228bcf49..89856fe4739 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -80,7 +80,7 @@ describe 'Recent searches', js: true, feature: true do set_recent_searches(project_1_local_storage_key, '["foo", "bar"]') visit namespace_project_issues_path(project_1.namespace, project_1) - all('.filtered-search-history-dropdown-item', visible: false)[0].trigger('click') + all('.filtered-search-history-dropdown-item', visible: false)[0].click wait_for_filtered_search('foo') expect(find('.filtered-search').value.strip).to eq('foo') @@ -94,7 +94,7 @@ describe 'Recent searches', js: true, feature: true do expect(items_before.count).to eq(1) - find('.filtered-search-history-clear-button', visible: false).trigger('click') + find('.filtered-search-history-clear-button', visible: false).click items_after = all('.filtered-search-history-dropdown-item', visible: false) expect(items_after.count).to eq(0) diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 96c24750250..cb3828fd70c 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -184,7 +184,7 @@ feature 'Issue Sidebar', feature: true do end def open_issue_sidebar - find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').trigger('click') + find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').click find('aside.right-sidebar.right-sidebar-expanded') end end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 2cff53539f3..17bdcb7d5c5 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -378,7 +378,7 @@ describe 'Issues', feature: true do it 'changes incoming email address token', js: true do find('.issue-email-modal-btn').click previous_token = find('input#issue_email').value - find('.incoming-email-token-reset').trigger('click') + find('.incoming-email-token-reset').click wait_for_requests diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 9409c32104b..16486118a9e 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -18,7 +18,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do all('button', text: 'Use ours').each do |button| - button.trigger('click') + button.click end end diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index e23dc2cd940..d603e4b1b4a 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -150,7 +150,7 @@ feature 'Diff note avatars', feature: true, js: true do page.within '.js-discussion-note-form' do find('.js-note-text').native.send_keys('Test') - find('.js-comment-button').trigger 'click' + find('.js-comment-button').click wait_for_requests end diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 4d549f3bdbb..0e23c3a8849 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -275,7 +275,7 @@ feature 'Diff notes resolve', feature: true, js: true do end page.within '.line-resolve-all-container' do - page.find('.discussion-next-btn').trigger('click') + page.find('.discussion-next-btn').click end expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb index 3a11ea3c8b2..207fae605d8 100644 --- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb +++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb @@ -90,7 +90,7 @@ feature 'Mini Pipeline Graph', :js, :feature do end it 'should close when toggle is clicked again' do - toggle.trigger('click') + toggle.click expect(toggle.find(:xpath, '..')).not_to have_selector('.mini-pipeline-graph-dropdown-menu') end diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index 14bc549c9f9..d1401b2e380 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -221,7 +221,7 @@ feature 'Merge requests > User posts diff notes', :js do def should_allow_dismissing_a_comment(line_holder, diff_side = nil) write_comment_on_line(line_holder, diff_side) - find('.js-close-discussion-note-form').trigger('click') + find('.js-close-discussion-note-form').click assert_comment_dismissal(line_holder) end @@ -259,7 +259,7 @@ feature 'Merge requests > User posts diff notes', :js do expect(line[:num]).to have_css comment_button_class - line[:num].find(comment_button_class).trigger 'click' + line[:num].find(comment_button_class).click end def write_comment_on_line(line_holder, diff_side) diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index aad522ee26e..094fd5bf63b 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -68,7 +68,7 @@ feature 'Merge Request versions', js: true, feature: true do page.within(diff_file_selector) do find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover' - find(".line_holder[id='#{line_code}'] button").trigger 'click' + find(".line_holder[id='#{line_code}'] button").click page.within("form[data-line-code='#{line_code}']") do fill_in "note[note]", with: "Typo, please fix" @@ -139,7 +139,7 @@ feature 'Merge Request versions', js: true, feature: true do page.within(diff_file_selector) do find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover' - find(".line_holder[id='#{line_code}'] button").trigger 'click' + find(".line_holder[id='#{line_code}'] button").click page.within("form[data-line-code='#{line_code}']") do fill_in "note[note]", with: "Typo, please fix" diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb index d368bc4d753..49bdf1a0247 100644 --- a/spec/features/profiles/preferences_spec.rb +++ b/spec/features/profiles/preferences_spec.rb @@ -44,7 +44,7 @@ describe 'Profile > Preferences', feature: true do expect(page.current_path).to eq starred_dashboard_projects_path end - find('.shortcuts-activity').trigger('click') + find('.shortcuts-activity').click expect(page).not_to have_content("You don't have starred projects yet") expect(page.current_path).to eq dashboard_projects_path diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 7668ce5f8be..ac5643b6837 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -55,7 +55,7 @@ describe 'Branches', feature: true do expect(page).to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 1) - find('.js-branch-fix .btn-remove').trigger(:click) + find('.js-branch-fix .btn-remove').click expect(page).not_to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 0) @@ -109,7 +109,7 @@ describe 'Branches', feature: true do expect(page).to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 1) - page.find('[data-target="#modal-delete-branch"]').trigger(:click) + page.find('[data-target="#modal-delete-branch"]').click expect(page).to have_css('.js-delete-branch[disabled]') fill_in 'delete_branch_input', with: 'fix' diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb index 1b680a56492..8796bf7cc6c 100644 --- a/spec/features/projects/group_links_spec.rb +++ b/spec/features/projects/group_links_spec.rb @@ -21,7 +21,7 @@ feature 'Project group links', :feature, :js do select2 group.id, from: '#link_group_id' fill_in 'expires_at_groups', with: (Time.current + 4.5.days).strftime('%Y-%m-%d') page.find('body').click - find('.btn-create').trigger('click') + find('.btn-create').click end it 'shows the expiration time with a warning class' do diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 31c93c75d25..bc8996d6ab1 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -375,7 +375,7 @@ feature 'Jobs', :feature do job.run! visit namespace_project_job_path(project.namespace, project, job) find('.js-cancel-job').click() - find('.js-retry-button').trigger('click') + find('.js-retry-button').click end it 'shows the right status and buttons', :js do diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 12c5ad45baf..5910daefba6 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -75,7 +75,7 @@ describe 'Pipeline', :feature, :js do end it 'should be possible to cancel the running build' do - find('#ci-badge-deploy .ci-action-icon-container').trigger('click') + find('#ci-badge-deploy .ci-action-icon-container').click expect(page).not_to have_content('Cancel running') end @@ -94,7 +94,7 @@ describe 'Pipeline', :feature, :js do end it 'should be possible to retry the success job' do - find('#ci-badge-build .ci-action-icon-container').trigger('click') + find('#ci-badge-build .ci-action-icon-container').click expect(page).not_to have_content('Retry job') end @@ -113,7 +113,7 @@ describe 'Pipeline', :feature, :js do end it 'should be possible to retry the failed build' do - find('#ci-badge-test .ci-action-icon-container').trigger('click') + find('#ci-badge-test .ci-action-icon-container').click expect(page).not_to have_content('Retry job') end @@ -132,7 +132,7 @@ describe 'Pipeline', :feature, :js do end it 'should be possible to play the manual job' do - find('#ci-badge-manual-build .ci-action-icon-container').trigger('click') + find('#ci-badge-manual-build .ci-action-icon-container').click expect(page).not_to have_content('Play job') end @@ -167,7 +167,7 @@ describe 'Pipeline', :feature, :js do context 'when retrying' do before do - find('.js-retry-button').trigger('click') + find('.js-retry-button').click end it { expect(page).not_to have_content('Retry') } @@ -233,7 +233,7 @@ describe 'Pipeline', :feature, :js do context 'when retrying' do before do - find('.js-retry-button').trigger('click') + find('.js-retry-button').click end it { expect(page).not_to have_content('Retry') } diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index db2d1a100a5..ef49a13903f 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -222,7 +222,7 @@ describe 'Pipelines', :feature, :js do context 'when canceling' do before do - find('.js-pipelines-cancel-button').trigger('click') + find('.js-pipelines-cancel-button').click end it 'indicates that pipeline was canceled' do @@ -335,14 +335,14 @@ describe 'Pipelines', :feature, :js do context 'when clicking a stage badge' do it 'should open a dropdown' do - find('.js-builds-dropdown-button').trigger('click') + find('.js-builds-dropdown-button').click expect(page).to have_link build.name end it 'should be possible to cancel pending build' do - find('.js-builds-dropdown-button').trigger('click') - find('a.js-ci-action-icon').trigger('click') + find('.js-builds-dropdown-button').click + find('a.js-ci-action-icon').click expect(page).to have_content('canceled') expect(build.reload).to be_canceled @@ -351,11 +351,11 @@ describe 'Pipelines', :feature, :js do context 'dropdown jobs list' do it 'should keep the dropdown open when the user ctr/cmd + clicks in the job name' do - find('.js-builds-dropdown-button').trigger('click') + find('.js-builds-dropdown-button').click execute_script('var e = $.Event("keydown", { keyCode: 64 }); $("body").trigger(e);') - find('.mini-pipeline-graph-dropdown-item').trigger('click') + find('.mini-pipeline-graph-dropdown-item').click expect(page).to have_selector('.js-ci-action-icon') end diff --git a/spec/features/projects/services/jira_service_spec.rb b/spec/features/projects/services/jira_service_spec.rb index c96d87e5708..58a05d92789 100644 --- a/spec/features/projects/services/jira_service_spec.rb +++ b/spec/features/projects/services/jira_service_spec.rb @@ -68,7 +68,7 @@ feature 'Setup Jira service', :feature, :js do expect(find('.flash-container-page')).to have_content 'Test failed.' expect(find('.flash-container-page')).to have_content 'Save anyway' - find('.flash-alert .flash-action').trigger('click') + find('.flash-alert .flash-action').click wait_for_requests expect(page).to have_content('JIRA activated.') diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index 94f6bb16730..824b3c81c8a 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -19,13 +19,13 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t login_as(user) visit namespace_project_path(project.namespace, project) - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end context "while creating a new wiki page" do context "when there are no spaces or hyphens in the page name" do it "rewrites relative links as expected" do - find('.add-new-wiki').trigger('click') + find('.add-new-wiki').click page.within '#modal-new-wiki' do fill_in :new_wiki_path, with: 'a/b/c/d' click_button 'Create page' @@ -92,7 +92,7 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "while editing a wiki page" do def create_wiki_page(path) - find('.add-new-wiki').trigger('click') + find('.add-new-wiki').click page.within '#modal-new-wiki' do fill_in :new_wiki_path, with: path diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 8912d575878..971bcab9569 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -8,7 +8,7 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do login_as(user) visit namespace_project_path(project.namespace, project) - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end context 'in the user namespace' do diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index aa9164dd979..6da1e02747f 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -9,7 +9,7 @@ feature 'Protected Branches', feature: true, js: true do end def set_protected_branch_name(branch_name) - find(".js-protected-branch-select").trigger('click') + find(".js-protected-branch-select").click find(".dropdown-input-field").set(branch_name) click_on("Create wildcard #{branch_name}") end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 89d4f536b20..c80dfc441d0 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -27,7 +27,7 @@ describe "Search", feature: true do end it 'shows group name after filtering' do - find('.js-search-group-dropdown').trigger('click') + find('.js-search-group-dropdown').click wait_for_requests page.within '.search-holder' do @@ -38,7 +38,7 @@ describe "Search", feature: true do end it 'filters by group projects after filtering by group' do - find('.js-search-group-dropdown').trigger('click') + find('.js-search-group-dropdown').click wait_for_requests page.within '.search-holder' do @@ -48,7 +48,7 @@ describe "Search", feature: true do expect(find('.js-search-group-dropdown')).to have_content(group.name) page.within('.project-filter') do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click wait_for_requests expect(page).to have_link(group_project.name_with_namespace) @@ -57,7 +57,7 @@ describe "Search", feature: true do it 'shows project name after filtering' do page.within('.project-filter') do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click wait_for_requests click_link project.name_with_namespace diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb index af25eebed13..f5010134883 100644 --- a/spec/features/tags/master_creates_tag_spec.rb +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -59,7 +59,7 @@ feature 'Master creates tag', feature: true do expect(ref_input.value).to eq 'master' expect(find('.dropdown-toggle-text')).to have_content 'master' - find('.js-branch-select').trigger('click') + find('.js-branch-select').click expect(find('.dropdown-menu')).to have_content 'empty-branch' end diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index feb2fe8a7d1..b6175673226 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -251,7 +251,7 @@ describe 'Dashboard Todos', feature: true do describe 'mark all as done', js: true do before do visit dashboard_todos_path - find('.js-todos-mark-all').trigger('click') + find('.js-todos-mark-all').click end it 'shows "All done" message!' do @@ -308,9 +308,9 @@ describe 'Dashboard Todos', feature: true do end def mark_all_and_undo - find('.js-todos-mark-all').trigger('click') + find('.js-todos-mark-all').click wait_for_requests - find('.js-todos-undo-all').trigger('click') + find('.js-todos-undo-all').click wait_for_requests end end diff --git a/spec/features/user_callout_spec.rb b/spec/features/user_callout_spec.rb index b84f834ff1e..848af5e3a4d 100644 --- a/spec/features/user_callout_spec.rb +++ b/spec/features/user_callout_spec.rb @@ -20,7 +20,7 @@ describe 'User Callouts', js: true do visit dashboard_projects_path within('.user-callout') do - find('.close').trigger('click') + find('.close').click end visit dashboard_projects_path diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb index bb4542b1683..da1074e5932 100644 --- a/spec/support/features/discussion_comments_shared_example.rb +++ b/spec/support/features/discussion_comments_shared_example.rb @@ -74,12 +74,12 @@ shared_examples 'discussion comments' do |resource_name| end it 'clicking the ul padding or divider should not change the text' do - find(menu_selector).trigger 'click' + find(menu_selector).click expect(page).to have_selector menu_selector expect(find(dropdown_selector)).to have_content 'Comment' - find("#{menu_selector} .divider").trigger 'click' + find("#{menu_selector} .divider").click expect(page).to have_selector menu_selector expect(find(dropdown_selector)).to have_content 'Comment' diff --git a/spec/support/protected_branches/access_control_ce_shared_examples.rb b/spec/support/protected_branches/access_control_ce_shared_examples.rb index 287d6bb13c3..71f622326a5 100644 --- a/spec/support/protected_branches/access_control_ce_shared_examples.rb +++ b/spec/support/protected_branches/access_control_ce_shared_examples.rb @@ -9,7 +9,7 @@ RSpec.shared_examples "protected branches > access control > CE" do allowed_to_push_button = find(".js-allowed-to-push") unless allowed_to_push_button.text == access_type_name - allowed_to_push_button.trigger('click') + allowed_to_push_button.click within(".dropdown.open .dropdown-menu") { click_on access_type_name } end end diff --git a/spec/support/protected_tags/access_control_ce_shared_examples.rb b/spec/support/protected_tags/access_control_ce_shared_examples.rb index 1d11512ef82..61fb1ffc47a 100644 --- a/spec/support/protected_tags/access_control_ce_shared_examples.rb +++ b/spec/support/protected_tags/access_control_ce_shared_examples.rb @@ -9,7 +9,7 @@ RSpec.shared_examples "protected tags > access control > CE" do allowed_to_create_button = find(".js-allowed-to-create") unless allowed_to_create_button.text == access_type_name - allowed_to_create_button.trigger('click') + allowed_to_create_button.click find('.create_access_levels-container .dropdown-menu li', match: :first) within('.create_access_levels-container .dropdown-menu') { click_on access_type_name } end diff --git a/spec/support/quick_actions_helpers.rb b/spec/support/quick_actions_helpers.rb index d2aaae7518f..361190aa352 100644 --- a/spec/support/quick_actions_helpers.rb +++ b/spec/support/quick_actions_helpers.rb @@ -3,7 +3,7 @@ module QuickActionsHelpers Sidekiq::Testing.fake! do page.within('.js-main-target-form') do fill_in 'note[note]', with: text - find('.js-comment-submit-button').trigger('click') + find('.js-comment-submit-button').click end end end diff --git a/spec/support/time_tracking_shared_examples.rb b/spec/support/time_tracking_shared_examples.rb index 0fa74f911f6..909d4e2ee8d 100644 --- a/spec/support/time_tracking_shared_examples.rb +++ b/spec/support/time_tracking_shared_examples.rb @@ -80,6 +80,6 @@ end def submit_time(quick_action) fill_in 'note[note]', with: quick_action - find('.js-comment-submit-button').trigger('click') + find('.js-comment-submit-button').click wait_for_requests end -- cgit v1.2.1 From 74fbc694de9a9cfe8a048c3c8d937f8e7068ce21 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 16 Jun 2017 23:25:48 -0700 Subject: Bump ChromeDriver to 2.30 --- scripts/prepare_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 07bbf901ad0..f9bf2238ab6 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -1,6 +1,6 @@ . scripts/utils.sh -wget -q https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip +wget -q https://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip unzip chromedriver_linux64.zip -d /usr/local/bin export SETUP_DB=${SETUP_DB:-true} -- cgit v1.2.1 From 3f81586ef0ab20533b8da1213bd9f60e1786dbaa Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 21 Jun 2017 09:44:35 -0700 Subject: Remove unnecessary ChromeDriver --- scripts/prepare_build.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index f9bf2238ab6..03de59f27ad 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -1,8 +1,5 @@ . scripts/utils.sh -wget -q https://chromedriver.storage.googleapis.com/2.30/chromedriver_linux64.zip -unzip chromedriver_linux64.zip -d /usr/local/bin - export SETUP_DB=${SETUP_DB:-true} export USE_BUNDLE_INSTALL=${USE_BUNDLE_INSTALL:-true} export BUNDLE_INSTALL_FLAGS="--without production --jobs $(nproc) --path vendor --retry 3 --quiet" -- cgit v1.2.1 From 0551944f6f6fc3041d283fa6fb7584db1011e412 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 2 Aug 2017 17:43:04 -0700 Subject: Bump CI image to Chrome 60.0 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d4def307c9..4507dd29e91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-59.0-node-7.1-postgresql-9.6" +image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-60.0-node-7.1-postgresql-9.6" .default-cache: &default-cache key: "ruby-233-with-yarn" -- cgit v1.2.1 From 2ea7d880093efcc03258d060a7f154353c27cb3c Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 2 Aug 2017 20:20:29 -0700 Subject: Remove unnecessary Docker image in karma job --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4507dd29e91..d93c1fad351 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -480,7 +480,6 @@ karma: <<: *dedicated-runner <<: *except-docs <<: *pull-cache - image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-59.0-node-7.1-postgresql-9.6" stage: test variables: BABEL_ENV: "coverage" -- cgit v1.2.1 From e8aabb07edfb215a9823d236c69d5eaa1348a0fa Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 2 Aug 2017 20:22:16 -0700 Subject: Remove unnecessary files caused by bad merge --- features/steps/dashboard/dashboard.rb | 83 -------- features/steps/dashboard/todos.rb | 191 ------------------ spec/features/todos/todos_spec.rb | 355 ---------------------------------- 3 files changed, 629 deletions(-) delete mode 100644 features/steps/dashboard/dashboard.rb delete mode 100644 features/steps/dashboard/todos.rb delete mode 100644 spec/features/todos/todos_spec.rb diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb deleted file mode 100644 index e221a550882..00000000000 --- a/features/steps/dashboard/dashboard.rb +++ /dev/null @@ -1,83 +0,0 @@ -class Spinach::Features::Dashboard < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedIssuable - - step 'I should see "New Project" link' do - expect(page).to have_link "New project" - end - - step 'I should see "Shop" project link' do - expect(page).to have_link "Shop" - end - - step 'I should see "Shop" project CI status' do - expect(page).to have_link "Commit: skipped" - end - - step 'I should see last push widget' do - expect(page).to have_content "You pushed to fix" - expect(page).to have_link "Create merge request" - end - - step 'I click "Create merge request" link' do - find_link("Create merge request", visible: false).click - end - - step 'I see prefilled new Merge Request page' do - expect(page).to have_selector('.merge-request-form') - expect(current_path).to eq new_namespace_project_merge_request_path(@project.namespace, @project) - expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s - expect(find("input#merge_request_source_branch").value).to eq "fix" - expect(find("input#merge_request_target_branch").value).to eq "master" - end - - step 'I have group with projects' do - @group = create(:group) - @project = create(:empty_project, namespace: @group) - @event = create(:closed_issue_event, project: @project) - - @project.team << [current_user, :master] - end - - step 'I should see projects list' do - @user.authorized_projects.all.each do |project| - expect(page).to have_link project.name_with_namespace - end - end - - step 'I should see groups list' do - Group.all.each do |group| - expect(page).to have_link group.name - end - end - - step 'group has a projects that does not belongs to me' do - @forbidden_project1 = create(:empty_project, group: @group) - @forbidden_project2 = create(:empty_project, group: @group) - end - - step 'I should see 1 project at group list' do - expect(find('span.last_activity/span')).to have_content('1') - end - - step 'I filter the list by label "feature"' do - page.within ".labels-filter" do - find('.dropdown').click - click_link "feature" - end - end - - step 'I should see "Bugfix1" in issues list' do - page.within "ul.content-list" do - expect(page).to have_content "Bugfix1" - end - end - - step 'project "Shop" has issue "Bugfix1" with label "feature"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Bugfix1", project: project, assignees: [current_user]) - issue.labels << project.labels.find_by(title: 'feature') - end -end diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb deleted file mode 100644 index 0b4a69b2a91..00000000000 --- a/features/steps/dashboard/todos.rb +++ /dev/null @@ -1,191 +0,0 @@ -class Spinach::Features::DashboardTodos < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedUser - include WaitForRequests - - step '"John Doe" is a developer of project "Shop"' do - project.team << [john_doe, :developer] - end - - step 'I am a developer of project "Enterprise"' do - enterprise.team << [current_user, :developer] - end - - step '"Mary Jane" is a developer of project "Shop"' do - project.team << [john_doe, :developer] - end - - step 'I have todos' do - create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED) - create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED) - note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?", project: project) - create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note) - create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED) - end - - step 'I should see todos assigned to me' do - merge_request_reference = merge_request.to_reference(full: true) - issue_reference = issue.to_reference(full: true) - - page.within('.todos-count') { expect(page).to have_content '4' } - expect(page).to have_content 'To do 4' - expect(page).to have_content 'Done 0' - - expect(page).to have_link project.name_with_namespace - should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title) - should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?") - should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title) - should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title) - end - - step 'I mark the todo as done' do - page.within('.todo:nth-child(1)') do - click_link 'Done' - end - - page.within('.todos-count') { expect(page).to have_content '3' } - expect(page).to have_content 'To do 3' - expect(page).to have_content 'Done 1' - should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_reversible) - end - - step 'I mark all todos as done' do - merge_request_reference = merge_request.to_reference(full: true) - issue_reference = issue.to_reference(full: true) - - find('.js-todos-mark-all').click - - page.within('.todos-count') { expect(page).to have_content '0' } - expect(page).to have_content 'To do 0' - expect(page).to have_content 'Done 4' - expect(page).to have_content "You're all done!" - expect('.prepend-top-default').not_to have_link project.name_with_namespace - should_not_see_todo "John Doe assigned you merge request #{merge_request_reference}" - should_not_see_todo "John Doe mentioned you on issue #{issue_reference}" - should_not_see_todo "John Doe assigned you issue #{issue_reference}" - should_not_see_todo "Mary Jane mentioned you on issue #{issue_reference}" - end - - step 'I should see the todo marked as done' do - find('.todos-done a').click - - expect(page).to have_link project.name_with_namespace - should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_irreversible) - end - - step 'I should see all todos marked as done' do - merge_request_reference = merge_request.to_reference(full: true) - issue_reference = issue.to_reference(full: true) - - find('.todos-done a').click - - expect(page).to have_link project.name_with_namespace - should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, state: :done_irreversible) - should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?", state: :done_irreversible) - should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title, state: :done_irreversible) - should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title, state: :done_irreversible) - end - - step 'I filter by "Enterprise"' do - click_button 'Project' - page.within '.dropdown-menu-project' do - click_link enterprise.name_with_namespace - end - end - - step 'I filter by "John Doe"' do - click_button 'Author' - page.within '.dropdown-menu-author' do - click_link john_doe.username - end - end - - step 'I filter by "Issue"' do - click_button 'Type' - page.within '.dropdown-menu-type' do - click_link 'Issue' - end - end - - step 'I filter by "Mentioned"' do - click_button 'Action' - page.within '.dropdown-menu-action' do - click_link 'Mentioned' - end - end - - step 'I should not see todos' do - expect(page).to have_content "You're all done!" - end - - step 'I should not see todos related to "Mary Jane" in the list' do - should_not_see_todo "Mary Jane mentioned you on issue #{issue.to_reference(full: true)}" - end - - step 'I should not see todos related to "Merge Requests" in the list' do - should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}" - end - - step 'I should not see todos related to "Assignments" in the list' do - should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}" - should_not_see_todo "John Doe assigned you issue #{issue.to_reference(full: true)}" - end - - step 'I click on the todo' do - find('.todo:nth-child(1)').click - end - - step 'I should be directed to the corresponding page' do - page.should have_css('.identifier', text: 'Merge request !1') - # Merge request page loads and issues a number of Ajax requests - wait_for_requests - end - - def should_see_todo(position, title, body, state: :pending) - page.within(".todo:nth-child(#{position})") do - expect(page).to have_content title - expect(page).to have_content body - - if state == :pending - expect(page).to have_link 'Done' - elsif state == :done_reversible - expect(page).to have_link 'Undo' - elsif state == :done_irreversible - expect(page).not_to have_link 'Undo' - expect(page).not_to have_link 'Done' - else - raise 'Invalid state given, valid states: :pending, :done_reversible, :done_irreversible' - end - end - end - - def should_not_see_todo(title) - expect(page).not_to have_visible_content title - end - - def have_visible_content(text) - have_css('*', text: text, visible: true) - end - - def john_doe - @john_doe ||= user_exists("John Doe", { username: "john_doe" }) - end - - def mary_jane - @mary_jane ||= user_exists("Mary Jane", { username: "mary_jane" }) - end - - def enterprise - @enterprise ||= Project.find_by(name: 'Enterprise') - end - - def issue - @issue ||= create(:issue, assignees: [current_user], project: project) - end - - def merge_request - @merge_request ||= create(:merge_request, assignee: current_user, source_project: project) - end -end diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb deleted file mode 100644 index 320777e97bf..00000000000 --- a/spec/features/todos/todos_spec.rb +++ /dev/null @@ -1,355 +0,0 @@ -require 'spec_helper' - -describe 'Dashboard Todos', feature: true do - let(:user) { create(:user) } - let(:author) { create(:user) } - let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:issue) { create(:issue, due_date: Date.today) } - - describe 'GET /dashboard/todos' do - context 'User does not have todos' do - before do - gitlab_sign_in(user) - visit dashboard_todos_path - end - it 'shows "All done" message' do - expect(page).to have_content "Todos let you see what you should do next." - end - end - - context 'User has a todo', js: true do - before do - create(:todo, :mentioned, user: user, project: project, target: issue, author: author) - gitlab_sign_in(user) - visit dashboard_todos_path - end - - it 'has todo present' do - expect(page).to have_selector('.todos-list .todo', count: 1) - end - - it 'shows due date as today' do - within first('.todo') do - expect(page).to have_content 'Due today' - end - end - - shared_examples 'deleting the todo' do - before do - within first('.todo') do - click_link 'Done' - end - end - - it 'is marked as done-reversible in the list' do - expect(page).to have_selector('.todos-list .todo.todo-pending.done-reversible') - end - - it 'shows Undo button' do - expect(page).to have_selector('.js-undo-todo', visible: true) - expect(page).to have_selector('.js-done-todo', visible: false) - end - - it 'updates todo count' do - expect(page).to have_content 'To do 0' - expect(page).to have_content 'Done 1' - end - - it 'has not "All done" message' do - expect(page).not_to have_selector('.todos-all-done') - end - end - - shared_examples 'deleting and restoring the todo' do - before do - within first('.todo') do - click_link 'Done' - wait_for_requests - click_link 'Undo' - end - end - - it 'is marked back as pending in the list' do - expect(page).not_to have_selector('.todos-list .todo.todo-pending.done-reversible') - expect(page).to have_selector('.todos-list .todo.todo-pending') - end - - it 'shows Done button' do - expect(page).to have_selector('.js-undo-todo', visible: false) - expect(page).to have_selector('.js-done-todo', visible: true) - end - - it 'updates todo count' do - expect(page).to have_content 'To do 1' - expect(page).to have_content 'Done 0' - end - end - - it_behaves_like 'deleting the todo' - it_behaves_like 'deleting and restoring the todo' - - context 'todo is stale on the page' do - before do - todos = TodosFinder.new(user, state: :pending).execute - TodoService.new.mark_todos_as_done(todos, user) - end - - it_behaves_like 'deleting the todo' - it_behaves_like 'deleting and restoring the todo' - end - end - - context 'User created todos for themself' do - before do - gitlab_sign_in(user) - end - - context 'issue assigned todo' do - before do - create(:todo, :assigned, user: user, project: project, target: issue, author: user) - visit dashboard_todos_path - end - - it 'shows issue assigned to yourself message' do - page.within('.js-todos-all') do - expect(page).to have_content("You assigned issue #{issue.to_reference(full: true)} to yourself") - end - end - end - - context 'marked todo' do - before do - create(:todo, :marked, user: user, project: project, target: issue, author: user) - visit dashboard_todos_path - end - - it 'shows you added a todo message' do - page.within('.js-todos-all') do - expect(page).to have_content("You added a todo for issue #{issue.to_reference(full: true)}") - expect(page).not_to have_content('to yourself') - end - end - end - - context 'mentioned todo' do - before do - create(:todo, :mentioned, user: user, project: project, target: issue, author: user) - visit dashboard_todos_path - end - - it 'shows you mentioned yourself message' do - page.within('.js-todos-all') do - expect(page).to have_content("You mentioned yourself on issue #{issue.to_reference(full: true)}") - expect(page).not_to have_content('to yourself') - end - end - end - - context 'directly_addressed todo' do - before do - create(:todo, :directly_addressed, user: user, project: project, target: issue, author: user) - visit dashboard_todos_path - end - - it 'shows you directly addressed yourself message' do - page.within('.js-todos-all') do - expect(page).to have_content("You directly addressed yourself on issue #{issue.to_reference(full: true)}") - expect(page).not_to have_content('to yourself') - end - end - end - - context 'approval todo' do - let(:merge_request) { create(:merge_request) } - - before do - create(:todo, :approval_required, user: user, project: project, target: merge_request, author: user) - visit dashboard_todos_path - end - - it 'shows you set yourself as an approver message' do - page.within('.js-todos-all') do - expect(page).to have_content("You set yourself as an approver for merge request #{merge_request.to_reference(full: true)}") - expect(page).not_to have_content('to yourself') - end - end - end - end - - context 'User has done todos', js: true do - before do - create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author) - gitlab_sign_in(user) - visit dashboard_todos_path(state: :done) - end - - it 'has the done todo present' do - expect(page).to have_selector('.todos-list .todo.todo-done', count: 1) - end - - describe 'restoring the todo' do - before do - within first('.todo') do - click_link 'Add todo' - end - end - - it 'is removed from the list' do - expect(page).not_to have_selector('.todos-list .todo.todo-done') - end - - it 'updates todo count' do - expect(page).to have_content 'To do 1' - expect(page).to have_content 'Done 0' - end - end - end - - context 'User has Todos with labels spanning multiple projects' do - before do - label1 = create(:label, project: project) - note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project) - create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id) - - project2 = create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) - label2 = create(:label, project: project2) - issue2 = create(:issue, project: project2) - note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2) - create(:todo, :mentioned, project: project2, target: issue2, user: user, note_id: note2.id) - - gitlab_sign_in(user) - visit dashboard_todos_path - end - - it 'shows page with two Todos' do - expect(page).to have_selector('.todos-list .todo', count: 2) - end - end - - context 'User has multiple pages of Todos' do - before do - allow(Todo).to receive(:default_per_page).and_return(1) - - # Create just enough records to cause us to paginate - create_list(:todo, 2, :mentioned, user: user, project: project, target: issue, author: author) - - gitlab_sign_in(user) - end - - it 'is paginated' do - visit dashboard_todos_path - - expect(page).to have_selector('.gl-pagination') - end - - it 'is has the right number of pages' do - visit dashboard_todos_path - - expect(page).to have_selector('.gl-pagination .page', count: 2) - end - - describe 'mark all as done', js: true do - before do - visit dashboard_todos_path - find('.js-todos-mark-all').click - end - - it 'shows "All done" message!' do - expect(page).to have_content 'To do 0' - expect(page).to have_content "You're all done!" - expect(page).not_to have_selector('.gl-pagination') - end - - it 'shows "Undo mark all as done" button' do - expect(page).to have_selector('.js-todos-mark-all', visible: false) - expect(page).to have_selector('.js-todos-undo-all', visible: true) - end - end - - describe 'undo mark all as done', js: true do - before do - visit dashboard_todos_path - end - - it 'shows the restored todo list' do - mark_all_and_undo - - expect(page).to have_selector('.todos-list .todo', count: 1) - expect(page).to have_selector('.gl-pagination') - expect(page).not_to have_content "You're all done!" - end - - it 'updates todo count' do - mark_all_and_undo - - expect(page).to have_content 'To do 2' - expect(page).to have_content 'Done 0' - end - - it 'shows "Mark all as done" button' do - mark_all_and_undo - - expect(page).to have_selector('.js-todos-mark-all', visible: true) - expect(page).to have_selector('.js-todos-undo-all', visible: false) - end - - context 'User has deleted a todo' do - before do - within first('.todo') do - click_link 'Done' - end - end - - it 'shows the restored todo list with the deleted todo' do - mark_all_and_undo - - expect(page).to have_selector('.todos-list .todo.todo-pending', count: 1) - end - end - - def mark_all_and_undo - find('.js-todos-mark-all').click - wait_for_requests - find('.js-todos-undo-all').click - wait_for_requests - end - end - end - - context 'User has a Todo in a project pending deletion' do - before do - deleted_project = create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC, pending_delete: true) - create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author) - create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author, state: :done) - gitlab_sign_in(user) - visit dashboard_todos_path - end - - it 'shows "All done" message' do - within('.todos-count') { expect(page).to have_content '0' } - expect(page).to have_content 'To do 0' - expect(page).to have_content 'Done 0' - expect(page).to have_selector('.todos-all-done', count: 1) - end - end - - context 'User has a Build Failed todo' do - let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: author) } - - before do - gitlab_sign_in user - visit dashboard_todos_path - end - - it 'shows the todo' do - expect(page).to have_content 'The build failed for merge request' - end - - it 'links to the pipelines for the merge request' do - href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target) - - expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href - end - end - end -end -- cgit v1.2.1 From fa68b81b8ead3c68a278729bfbcb621a9c6197e3 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 2 Aug 2017 22:13:46 -0700 Subject: Change trigger('click') -> click for Chrome Done via: ``` git grep --name-only trigger\(\'click\'\) | xargs sed -i -e "s/trigger('click')/click/g" ``` --- spec/features/dashboard/issues_spec.rb | 2 +- spec/features/dashboard/todos/todos_spec.rb | 6 +++--- spec/features/issues/gfm_autocomplete_spec.rb | 2 +- spec/features/profiles/user_visits_notifications_tab_spec.rb | 2 +- spec/features/projects/environments/environments_spec.rb | 2 +- spec/features/projects/wiki/user_creates_wiki_page_spec.rb | 8 ++++---- spec/features/tags/master_creates_tag_spec.rb | 2 +- .../integrations/integration_settings_form_spec.js | 2 +- spec/javascripts/issue_spec.js | 10 +++++----- spec/javascripts/merge_request_notes_spec.js | 2 +- .../pipeline_schedules/setup_pipeline_variable_list_spec.js | 2 +- spec/javascripts/u2f/authenticate_spec.js | 8 ++++---- spec/javascripts/u2f/register_spec.js | 12 ++++++------ 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index a11499ba191..c53b8bdc002 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -80,7 +80,7 @@ RSpec.describe 'Dashboard Issues' do end it 'shows the new issue page', :js do - find('.new-project-item-select-button').trigger('click') + find('.new-project-item-select-button').click wait_for_requests find('.select2-results li').click diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb index c2a61cf5aff..e6795c8470f 100644 --- a/spec/features/dashboard/todos/todos_spec.rb +++ b/spec/features/dashboard/todos/todos_spec.rb @@ -252,7 +252,7 @@ feature 'Dashboard Todos' do describe 'mark all as done', js: true do before do visit dashboard_todos_path - find('.js-todos-mark-all').trigger('click') + find('.js-todos-mark-all').click end it 'shows "All done" message!' do @@ -309,9 +309,9 @@ feature 'Dashboard Todos' do end def mark_all_and_undo - find('.js-todos-mark-all').trigger('click') + find('.js-todos-mark-all').click wait_for_requests - find('.js-todos-undo-all').trigger('click') + find('.js-todos-undo-all').click wait_for_requests end end diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 1b36f16e8b6..2f69e299326 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -19,7 +19,7 @@ feature 'GFM autocomplete', js: true do find('#issue-description').native.send_keys("@#{user.name[0...3]}") - find('.atwho-view .cur').trigger('click') + find('.atwho-view .cur').click click_button 'Save changes' diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb index e98cec79d87..c2c17df67fb 100644 --- a/spec/features/profiles/user_visits_notifications_tab_spec.rb +++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb @@ -13,7 +13,7 @@ feature 'User visits the notifications tab', js: true do it 'changes the project notifications setting' do expect(page).to have_content('Notifications') - first('#notifications-button').trigger('click') + first('#notifications-button').click click_link('On mention') expect(page).to have_content('On mention') diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 36cf307fbe2..70e6a1ff1cc 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -151,7 +151,7 @@ feature 'Environments page', :js do find('.js-dropdown-play-icon-container').click expect(page).to have_content(action.name.humanize) - expect { find('.js-manual-action-link').trigger('click') } + expect { find('.js-manual-action-link').click } .not_to change { Ci::Pipeline.count } end diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 78c619f6301..c1e28752c99 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -15,7 +15,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do context 'when wiki is empty' do before do - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end scenario 'commit message field has value "Create home"' do @@ -70,7 +70,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do context 'when wiki is not empty' do before do WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end context 'via the "new wiki page" page' do @@ -161,7 +161,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do context 'when wiki is empty' do before do - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end scenario 'commit message field has value "Create home"' do @@ -183,7 +183,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do context 'when wiki is not empty' do before do WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click end scenario 'via the "new wiki page" page' do diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb index 35e1ca32f67..ed7c5bd6592 100644 --- a/spec/features/tags/master_creates_tag_spec.rb +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -63,7 +63,7 @@ feature 'Master creates tag' do expect(ref_input.value).to eq 'master' expect(find('.dropdown-toggle-text')).to have_content 'master' - find('.js-branch-select').trigger('click') + find('.js-branch-select').click expect(find('.dropdown-menu')).to have_content 'empty-branch' end diff --git a/spec/javascripts/integrations/integration_settings_form_spec.js b/spec/javascripts/integrations/integration_settings_form_spec.js index 3daeb91b1e2..77ade71cc55 100644 --- a/spec/javascripts/integrations/integration_settings_form_spec.js +++ b/spec/javascripts/integrations/integration_settings_form_spec.js @@ -168,7 +168,7 @@ describe('IntegrationSettingsForm', () => { expect($flashAction).toBeDefined(); spyOn(integrationSettingsForm.$form, 'submit'); - $flashAction.trigger('click'); + $flashAction.click; expect(integrationSettingsForm.$form.submit).toHaveBeenCalled(); }); diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 0c8c4d2cea6..2c22b4db077 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -128,7 +128,7 @@ describe('Issue', function() { }); it(`${action}s the issue`, function() { - this.$triggeredButton.trigger('click'); + this.$triggeredButton.click; this.issueStateDeferred.resolve({ id: 34 }); @@ -143,7 +143,7 @@ describe('Issue', function() { }); it(`fails to ${action} the issue if saved:false`, function() { - this.$triggeredButton.trigger('click'); + this.$triggeredButton.click; this.issueStateDeferred.resolve({ saved: false }); @@ -159,7 +159,7 @@ describe('Issue', function() { }); it(`fails to ${action} the issue if HTTP error occurs`, function() { - this.$triggeredButton.trigger('click'); + this.$triggeredButton.click; this.issueStateDeferred.reject(); this.canCreateBranchDeferred.resolve({ can_create_branch: isIssueInitiallyOpen @@ -173,7 +173,7 @@ describe('Issue', function() { }); it('disables the new branch button if Ajax call fails', function() { - this.$triggeredButton.trigger('click'); + this.$triggeredButton.click; this.issueStateDeferred.reject(); this.canCreateBranchDeferred.reject(); @@ -184,7 +184,7 @@ describe('Issue', function() { Issue.$btnNewBranch = $(); this.canCreateBranchDeferred = null; - this.$triggeredButton.trigger('click'); + this.$triggeredButton.click; this.issueStateDeferred.reject(); }); }); diff --git a/spec/javascripts/merge_request_notes_spec.js b/spec/javascripts/merge_request_notes_spec.js index 395dc560671..f0ec22792d3 100644 --- a/spec/javascripts/merge_request_notes_spec.js +++ b/spec/javascripts/merge_request_notes_spec.js @@ -84,7 +84,7 @@ describe('Merge request notes', () => { spyOnEvent('.note:last .js-note-edit', 'click'); - $('.js-discussion-reply-button').trigger('click'); + $('.js-discussion-reply-button').click; setTimeout(() => { $('.js-note-text').trigger(upArrowEvent); diff --git a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js index 5b316b319a5..162a393f6d4 100644 --- a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js +++ b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js @@ -92,7 +92,7 @@ describe('Pipeline Variable List', () => { }); it('should remove the row when clicking the remove button', () => { - $markup.find('.js-row-remove-button').trigger('click'); + $markup.find('.js-row-remove-button').click; expect($markup.find('.js-row').length).toBe(0); }); diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js index a160c86308d..037e0aefdf4 100644 --- a/spec/javascripts/u2f/authenticate_spec.js +++ b/spec/javascripts/u2f/authenticate_spec.js @@ -44,7 +44,7 @@ import './mock_u2f_device'; it("displays an error message", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-login-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToAuthenticateRequest({ errorCode: "error!" }); @@ -54,14 +54,14 @@ import './mock_u2f_device'; return it("allows retrying authentication after an error", function() { var retryButton, setupButton; setupButton = this.container.find("#js-login-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToAuthenticateRequest({ errorCode: "error!" }); retryButton = this.container.find("#js-u2f-try-again"); - retryButton.trigger('click'); + retryButton.click; setupButton = this.container.find("#js-login-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToAuthenticateRequest({ deviceData: "this is data from the device" }); diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js index a445c80f2af..2c80ac9aa69 100644 --- a/spec/javascripts/u2f/register_spec.js +++ b/spec/javascripts/u2f/register_spec.js @@ -23,7 +23,7 @@ import './mock_u2f_device'; var deviceResponse, inProgressMessage, registeredMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); expect(setupButton.text()).toBe('Setup new U2F device'); - setupButton.trigger('click'); + setupButton.click; inProgressMessage = this.container.children("p"); expect(inProgressMessage.text()).toContain("Trying to communicate with your device"); this.u2fDevice.respondToRegisterRequest({ @@ -38,7 +38,7 @@ import './mock_u2f_device'; it("doesn't allow the same device to be registered twice (for the same user", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToRegisterRequest({ errorCode: 4 }); @@ -48,7 +48,7 @@ import './mock_u2f_device'; it("displays an error message for other errors", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToRegisterRequest({ errorCode: "error!" }); @@ -58,14 +58,14 @@ import './mock_u2f_device'; return it("allows retrying registration after an error", function() { var registeredMessage, retryButton, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToRegisterRequest({ errorCode: "error!" }); retryButton = this.container.find("#U2FTryAgain"); - retryButton.trigger('click'); + retryButton.click; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.trigger('click'); + setupButton.click; this.u2fDevice.respondToRegisterRequest({ deviceData: "this is data from the device" }); -- cgit v1.2.1 From ded77e21b38dbb65aec2aeae42de02e6571fe01a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 2 Aug 2017 22:25:57 -0700 Subject: Rename remove_cookie -> delete_cookie in Capybara helper for Selenium driver --- spec/support/capybara_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb index 3eb7bea3227..0106b4e656a 100644 --- a/spec/support/capybara_helpers.rb +++ b/spec/support/capybara_helpers.rb @@ -38,7 +38,7 @@ module CapybaraHelpers # Simulate a browser restart by clearing the session cookie. def clear_browser_session - page.driver.remove_cookie('_gitlab_session') + page.driver.delete_cookie('_gitlab_session') end end -- cgit v1.2.1 From 50701b58bfa4a36c8313af14b68744cc1fce36f6 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 9 Aug 2017 22:32:30 -0700 Subject: Fix implementation of resize_window for Selenium --- spec/support/mobile_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/mobile_helpers.rb b/spec/support/mobile_helpers.rb index 431f20a2a5c..3b9eb84e824 100644 --- a/spec/support/mobile_helpers.rb +++ b/spec/support/mobile_helpers.rb @@ -12,6 +12,6 @@ module MobileHelpers end def resize_window(width, height) - page.driver.resize_window width, height + Capybara.current_session.current_window.resize_to(width, height) end end -- cgit v1.2.1 From 4b5483321a7b1c1d9eb2f473bfded433feb5c64b Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 9 Aug 2017 23:06:28 -0700 Subject: Change trigger('focus') -> click --- spec/features/admin/admin_users_impersonation_tokens_spec.rb | 2 +- spec/features/profiles/personal_access_tokens_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index 034682dae27..e36ead6667f 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -24,7 +24,7 @@ describe 'Admin > Users > Impersonation Tokens', js: true do fill_in "Name", with: name # Set date to 1st of next month - find_field("Expires at").trigger('focus') + find_field("Expires at").click find(".pika-next").click click_on "1" diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index f3124bbf29e..2db8c6dadc6 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -34,7 +34,7 @@ describe 'Profile > Personal Access Tokens', js: true do fill_in "Name", with: name # Set date to 1st of next month - find_field("Expires at").trigger('focus') + find_field("Expires at").click find(".pika-next").click click_on "1" -- cgit v1.2.1 From a5e096ceaa468ba3f3ff3b70369e2b16d76e55e9 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 11 Aug 2017 22:01:00 -0700 Subject: Expand Chrome window size to make specs pass --- spec/support/capybara.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 53a90cdb26f..693de9a3118 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -11,7 +11,7 @@ Capybara.javascript_driver = :chrome Capybara.register_driver :chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( 'chromeOptions' => { - 'args' => %w[headless no-sandbox disable-gpu] + 'args' => %w[headless no-sandbox disable-gpu --window-size=1240,1400] } ) -- cgit v1.2.1 From 08172ff595f3c28080e2e5a45d15e28007d5206e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 11 Aug 2017 23:02:21 -0700 Subject: Expand Spinach window size and remove unsupported trigger calls --- features/steps/project/merge_requests.rb | 2 -- features/steps/shared/diff_note.rb | 2 -- features/support/capybara.rb | 2 +- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index d6c1c73ae83..5cd66723612 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -356,8 +356,6 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see a discussion by user "John Doe" has started on diff' do - # Trigger a refresh of notes - execute_script("$(document).trigger('visibilitychange');") wait_for_requests page.within(".notes .discussion") do page.should have_content "#{user_exists("John Doe").name} #{user_exists("John Doe").to_reference} started a discussion" diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index 312187cbd0f..4f2f33cf768 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -227,12 +227,10 @@ module SharedDiffNote end def click_diff_line(code) - find(".line_holder[id='#{code}'] td:nth-of-type(1)").trigger 'mouseover' find(".line_holder[id='#{code}'] button").click end def click_parallel_diff_line(code, line_type) - find(".line_holder.parallel .diff-line-num[id='#{code}']").trigger 'mouseover' find(".line_holder.parallel button[data-line-code='#{code}']").click end end diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 595577804bd..20abb504dc6 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -7,7 +7,7 @@ Capybara.javascript_driver = :chrome Capybara.register_driver :chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( 'chromeOptions' => { - 'args' => %w[headless no-sandbox disable-gpu] + 'args' => %w[headless no-sandbox disable-gpu --window-size=1240,1400] } ) -- cgit v1.2.1 From 7b70d01279ea7de784b63ce41c52d460b93afbf9 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 11 Aug 2017 23:16:49 -0700 Subject: Add return value in form input to make add member specs pass --- .../projects/members/master_adds_member_with_expiration_date_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index cd621b6b3ce..3ae5af80606 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -20,7 +20,7 @@ feature 'Projects > Members > Master adds member with expiration date', js: true page.within '.users-project-form' do select2(new_member.id, from: '#user_ids', multiple: true) - fill_in 'expires_at', with: date.to_s(:medium) + fill_in 'expires_at', with: date.to_s(:medium) + "\n" click_on 'Add to project' end @@ -37,7 +37,7 @@ feature 'Projects > Members > Master adds member with expiration date', js: true visit project_project_members_path(project) page.within "#project_member_#{new_member.project_members.first.id}" do - find('.js-access-expiration-date').set date.to_s(:medium) + find('.js-access-expiration-date').set date.to_s(:medium) + "\n" wait_for_requests expect(page).to have_content('Expires in 3 days') end -- cgit v1.2.1 From 0d6133b98ded73f6fe4c33e04473bb3f03015ea7 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 21:32:03 -0700 Subject: Bump Capybara version for Chrome headless fixes --- Gemfile | 2 +- Gemfile.lock | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 674f758f456..583d450ec32 100644 --- a/Gemfile +++ b/Gemfile @@ -331,7 +331,7 @@ group :development, :test do # Generate Fake data gem 'ffaker', '~> 2.4' - gem 'capybara', '~> 2.6.2' + gem 'capybara', '~> 2.15' gem 'capybara-screenshot', '~> 1.0.0' gem 'selenium-webdriver', '~> 2.53' diff --git a/Gemfile.lock b/Gemfile.lock index 4898a515d36..b2a0b3e17f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -98,9 +98,9 @@ GEM bundler (~> 1.2) thor (~> 0.18) byebug (9.0.6) - capybara (2.6.2) + capybara (2.15.1) addressable - mime-types (>= 1.16) + mini_mime (>= 0.1.3) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) @@ -465,6 +465,7 @@ GEM method_source (0.8.2) mime-types (2.99.3) mimemagic (0.3.0) + mini_mime (0.1.4) mini_portile2 (2.1.0) minitest (5.7.0) mmap2 (2.2.7) @@ -908,7 +909,7 @@ GEM expression_parser rinku xml-simple (1.1.5) - xpath (2.0.0) + xpath (2.1.0) nokogiri (~> 1.3) PLATFORMS @@ -940,7 +941,7 @@ DEPENDENCIES browser (~> 2.2) bullet (~> 5.5.0) bundler-audit (~> 0.5.0) - capybara (~> 2.6.2) + capybara (~> 2.15) capybara-screenshot (~> 1.0.0) carrierwave (~> 1.1) charlock_holmes (~> 0.7.3) -- cgit v1.2.1 From 2901fc1390370a38944cd2c1ea88bf0fd3839a5a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 21:49:56 -0700 Subject: Make protected branches spec work in headless Chrome This needs two patches in Capybara: * https://github.com/teamcapybara/capybara/pull/1902 * https://github.com/teamcapybara/capybara/pull/1903 --- spec/features/projects/branches_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index b7ceac79c40..26902589c33 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -93,7 +93,11 @@ describe 'Branches' do expect(page).to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 1) - find('.js-branch-fix .btn-remove').click + # To work with Chrome headless, this needs an updated version of + # Capybara with two bug fixes: + # * https://github.com/teamcapybara/capybara/pull/1902/ + # * https://github.com/teamcapybara/capybara/pull/1903/ + accept_alert { find('.js-branch-fix .btn-remove').click } expect(page).not_to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 0) -- cgit v1.2.1 From ad73d24235ef22f9012b30be9d9492b11b46ca58 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 22:34:01 -0700 Subject: Bump selenium-webdriver to 3.5.0 to make Capybara work properly --- Gemfile | 2 +- Gemfile.lock | 6 ++---- features/support/capybara.rb | 2 +- spec/support/capybara.rb | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 583d450ec32..29325611fba 100644 --- a/Gemfile +++ b/Gemfile @@ -333,7 +333,7 @@ group :development, :test do gem 'capybara', '~> 2.15' gem 'capybara-screenshot', '~> 1.0.0' - gem 'selenium-webdriver', '~> 2.53' + gem 'selenium-webdriver', '~> 3.5' gem 'spring', '~> 2.0.0' gem 'spring-commands-rspec', '~> 1.0.4' diff --git a/Gemfile.lock b/Gemfile.lock index b2a0b3e17f6..f8c648319a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -778,10 +778,9 @@ GEM activesupport (>= 3.1) select2-rails (3.5.9.3) thor (~> 0.14) - selenium-webdriver (2.53.4) + selenium-webdriver (3.5.0) childprocess (~> 0.5) rubyzip (~> 1.0) - websocket (~> 1.0) sentry-raven (2.5.3) faraday (>= 0.7.6, < 1.0) settingslogic (2.0.9) @@ -903,7 +902,6 @@ GEM hashdiff webpack-rails (0.9.10) railties (>= 3.2.0) - websocket (1.2.4) wikicloth (0.8.1) builder expression_parser @@ -1100,7 +1098,7 @@ DEPENDENCIES scss_lint (~> 0.54.0) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) - selenium-webdriver (~> 2.53) + selenium-webdriver (~> 3.5) sentry-raven (~> 2.5.3) settingslogic (~> 2.0.9) sham_rack (~> 1.3.6) diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 20abb504dc6..8628a38eaac 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -6,7 +6,7 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 Capybara.javascript_driver = :chrome Capybara.register_driver :chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( - 'chromeOptions' => { + chromeOptions: { 'args' => %w[headless no-sandbox disable-gpu --window-size=1240,1400] } ) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 693de9a3118..b5b98f19694 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -10,7 +10,7 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 Capybara.javascript_driver = :chrome Capybara.register_driver :chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( - 'chromeOptions' => { + chromeOptions: { 'args' => %w[headless no-sandbox disable-gpu --window-size=1240,1400] } ) -- cgit v1.2.1 From 1eade5854a5cbf5fc9e8a326e976c55006e100de Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 22:48:02 -0700 Subject: Fix trigger spec by surrounding the accept_confirm in the right place --- spec/features/triggers_spec.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 47664de469a..477798e3826 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -94,12 +94,13 @@ feature 'Triggers', js: true do scenario 'take trigger ownership' do # See if "Take ownership" on trigger works post trigger creation - find('a.btn-trigger-take-ownership').click page.accept_confirm do - expect(page.find('.flash-notice')).to have_content 'Trigger was re-assigned.' - expect(page.find('.triggers-list')).to have_content trigger_title - expect(page.find('.triggers-list .trigger-owner')).to have_content user.name + find('a.btn-trigger-take-ownership').click end + + expect(page.find('.flash-notice')).to have_content 'Trigger was re-assigned.' + expect(page.find('.triggers-list')).to have_content trigger_title + expect(page.find('.triggers-list .trigger-owner')).to have_content user.name end end -- cgit v1.2.1 From f64f06f6516bea10a0ac738c21961db033daa978 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 22:51:35 -0700 Subject: Change trigger('click') calls to click --- spec/features/issues/issue_sidebar_spec.rb | 8 ++++---- spec/features/merge_requests/form_spec.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 396cca6a3e2..a8983a016dc 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -130,8 +130,8 @@ feature 'Issue Sidebar' do it 'adds new label' do page.within('.block.labels') do fill_in 'new_label_name', with: 'wontfix' - page.find('.suggest-colors a', match: :first).trigger('click') - page.find('button', text: 'Create').trigger('click') + page.find('.suggest-colors a', match: :first).click + page.find('button', text: 'Create').click page.within('.dropdown-page-one') do expect(page).to have_content 'wontfix' @@ -142,8 +142,8 @@ feature 'Issue Sidebar' do it 'shows error message if label title is taken' do page.within('.block.labels') do fill_in 'new_label_name', with: label.title - page.find('.suggest-colors a', match: :first).trigger('click') - page.find('button', text: 'Create').trigger('click') + page.find('.suggest-colors a', match: :first).click + page.find('button', text: 'Create').click page.within('.dropdown-page-two') do expect(page).to have_content 'Title has already been taken' diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb index 89410b0e90f..75988cfceae 100644 --- a/spec/features/merge_requests/form_spec.rb +++ b/spec/features/merge_requests/form_spec.rb @@ -41,7 +41,7 @@ describe 'New/edit merge request', :js do expect(page).to have_content user2.name end - find('a', text: 'Assign to me').trigger('click') + find('a', text: 'Assign to me').click expect(find('input[name="merge_request[assignee_id]"]', visible: false).value).to match(user.id.to_s) page.within '.js-assignee-search' do expect(page).to have_content user.name -- cgit v1.2.1 From 1ddfe8ca33ab2ccd7badc5ef52ea7d88da46b32f Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 23:01:24 -0700 Subject: Remove a few HTTP status checks as these are not supported in Selenium --- spec/features/projects/environments/environment_spec.rb | 1 - spec/features/projects/pipelines/pipelines_spec.rb | 1 - 2 files changed, 2 deletions(-) diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index 56addd64056..c9f12e877b3 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -198,7 +198,6 @@ feature 'Environment' do end it 'renders a correct environment folder' do - expect(page).to have_http_status(:ok) expect(page).to have_content('Environments / staging-1.0') end end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 92479558553..b6a66a6d0c8 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -515,7 +515,6 @@ describe 'Pipelines', :js do let(:project) { create(:project, :public, :repository) } it { expect(page).to have_content 'Build with confidence' } - it { expect(page).to have_http_status(:success) } end context 'when project is private' do -- cgit v1.2.1 From b03fe23d536cda3f65965f31c4e3965e66858616 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 23:01:45 -0700 Subject: Remove unsupported `network_traffic` in specs --- spec/features/snippets/notes_on_personal_snippets_spec.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index f1d0905738b..b7245c1d92b 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -74,18 +74,15 @@ describe 'Comments on personal snippets', :js do it 'should not have autocomplete' do wait_for_requests - request_count_before = page.driver.network_traffic.count find('#note_note').native.send_keys('') fill_in 'note[note]', with: '@' wait_for_requests - request_count_after = page.driver.network_traffic.count # This selector probably won't be in place even if autocomplete was enabled # but we want to make sure expect(page).not_to have_selector('.atwho-view') - expect(request_count_before).to eq(request_count_after) end end -- cgit v1.2.1 From 12e6cb71c6ef3fbbad6961eb06ebf6d41e9eb26a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 12 Aug 2017 23:08:47 -0700 Subject: Fix pipelines spec by surrounding click with accept_confirm --- spec/features/projects/pipelines/pipelines_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index b6a66a6d0c8..2d5407747af 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -103,7 +103,7 @@ describe 'Pipelines', :js do context 'when canceling' do before do - find('.js-pipelines-cancel-button').click + accept_confirm { find('.js-pipelines-cancel-button').click } wait_for_requests end -- cgit v1.2.1 From 93077d76f2e6f284f0b64c106c2c56d924ee0e99 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 08:31:17 -0700 Subject: Fix merge request Spinach test for Selenium --- features/steps/project/merge_requests.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 5cd66723612..d0be8a915cd 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -418,7 +418,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click link "Reopen"' do - first(:css, '.reopen-mr-link').click + all(:css, '.reopen-mr-link').last.click end step 'I should see reopened merge request "Bug NS-04"' do -- cgit v1.2.1 From a7c1ce3fdb6842fe13f13bd059ee618b230d000a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 15:27:36 -0700 Subject: Fix Spinach spec for deleting branches --- features/steps/project/commits/branches.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index ccaf3237815..080e59f789b 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -70,13 +70,12 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps step "I click branch 'improve/awesome' delete link" do page.within '.js-branch-improve\/awesome' do - find('.btn-remove').click - sleep 0.05 + accept_alert { find('.btn-remove').click } end end step "I should not see branch 'improve/awesome'" do - expect(page.all(visible: true)).not_to have_content 'improve/awesome' + expect(page).to have_css('.js-branch-improve\\/awesome', visible: :hidden) end def select_branch(branch_name) -- cgit v1.2.1 From a2cd32b75c3b9492dfe0b8c2219bf45552ed0600 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 15:40:33 -0700 Subject: Fix snippets spec: send_keys only works with text areas --- features/steps/project/snippets.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index b0407d3f07d..d9bf373a0d7 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -58,7 +58,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps fill_in "project_snippet_title", with: "Snippet three" fill_in "project_snippet_file_name", with: "my_snippet.rb" page.within('.file-editor') do - find('.ace_editor').native.send_keys 'Content of snippet three' + find('.ace_text-input').native.send_keys 'Content of snippet three' end click_button "Create snippet" wait_for_requests -- cgit v1.2.1 From 247138d4f6335f9d1dc92cdedab305e8db28ed25 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 15:55:36 -0700 Subject: Accept the confirm modal to make comment on commit spec to pass --- features/steps/shared/note.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index 80187b83fee..9de6a3ce771 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -14,7 +14,7 @@ module SharedNote note.find('.more-actions').click note.find('.more-actions .dropdown-menu li', match: :first) - find(".js-note-delete").click + accept_confirm { find(".js-note-delete").click } end end -- cgit v1.2.1 From 3e644d4b065defc3ebf8cb6d1fc6198b0b366c9e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 22:30:37 -0700 Subject: Fix U2F spec in headless Chrome There were a number of issues with this spec: 1. The deletion of the U2F device needed an `accept_confirm` block 2. The "We heard back from your U2F device" message is shown only briefly before the JavaScript handler submits the form. The only way to fix this is to put a delay in the submission. 3. The "Remember Me" field can't be checked in step 2 for the same reason. --- spec/features/u2f_spec.rb | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index f3662cb184f..915d90859ba 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -79,7 +79,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do first_u2f_device = register_u2f_device second_u2f_device = register_u2f_device(name: 'My other device') - click_on "Delete", match: :first + accept_confirm { click_on "Delete", match: :first } expect(page).to have_content('Successfully deleted') expect(page.body).not_to match(first_u2f_device.name) @@ -162,7 +162,6 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do @u2f_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_css('.sign-out-link', visible: false) end end @@ -174,23 +173,10 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do @u2f_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_css('.sign-out-link', visible: false) end end - it 'persists remember_me value via hidden field' do - gitlab_sign_in(user, remember: true) - - @u2f_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') - - within 'div#js-authenticate-u2f' do - field = first('input#user_remember_me', visible: false) - expect(field.value).to eq '1' - end - end - describe "when a given U2F device has already been registered by another user" do describe "but not the current user" do it "does not allow logging in with that particular device" do -- cgit v1.2.1 From fab88bc3a1cd6983e8e66ce008f56c495ed8a59b Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 13 Aug 2017 23:39:43 -0700 Subject: Fix a few failing tests in Spinach merge request specs for Selenium --- features/steps/project/merge_requests.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index d0be8a915cd..7beb1ef45dd 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -1,4 +1,5 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps + include Select2Helper include SharedAuthentication include SharedIssuable include SharedProject @@ -330,7 +331,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps find('.more-actions').click find('.more-actions .dropdown-menu li', match: :first) - find('.js-note-delete').click + accept_confirm { find('.js-note-delete').click } end end @@ -534,7 +535,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I select a new target branch' do - select "feature", from: "merge_request_target_branch" + capybara_select2('feature_conflict') click_button 'Save' end -- cgit v1.2.1 From 767dffcc34f5088ea472160380a84c093aa02c73 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 15 Aug 2017 13:44:57 -0700 Subject: Fix a few failing specs due to missing accept_confirm --- features/steps/project/issues/milestones.rb | 2 +- spec/features/merge_requests/diff_notes_avatars_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index fe94eb03acd..8d1c23d40a6 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -63,7 +63,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I click link to remove milestone' do - click_link 'Delete' + accept_alert { click_link 'Delete' } end step 'I should see no milestones' do diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 737045413bf..a3737b30721 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -115,7 +115,7 @@ feature 'Diff note avatars', js: true do open_more_actions_dropdown(note) page.within find(".note-row-#{note.id}") do - find('.js-note-delete').click + accept_confirm { find('.js-note-delete').click } end wait_for_requests -- cgit v1.2.1 From 7b5722c890da4f50a69a117ff043e2ec5778010a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 16 Aug 2017 01:23:27 -0700 Subject: Fix a number of failed Spinach tests with Selenium needing accept_alert --- features/steps/project/builds/summary.rb | 2 +- features/steps/project/issues/labels.rb | 2 +- features/steps/project/issues/milestones.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/steps/project/builds/summary.rb b/features/steps/project/builds/summary.rb index 20a5c873ecd..40d373a680b 100644 --- a/features/steps/project/builds/summary.rb +++ b/features/steps/project/builds/summary.rb @@ -18,7 +18,7 @@ class Spinach::Features::ProjectBuildsSummary < Spinach::FeatureSteps end step 'I click erase build button' do - click_link 'Erase' + accept_confirm { click_link 'Erase' } end step 'recent build has been erased' do diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index dac18c537ac..196e0fff63a 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I delete all labels' do page.within '.labels' do page.all('.remove-row').each do - first('.remove-row').click + accept_confirm { first('.remove-row').click } end end end diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index 8d1c23d40a6..fe94eb03acd 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -63,7 +63,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I click link to remove milestone' do - accept_alert { click_link 'Delete' } + click_link 'Delete' end step 'I should see no milestones' do -- cgit v1.2.1 From ebd5c309a8182f842f3e1b95047ed9e03bb0a1e6 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 16 Aug 2017 01:44:53 -0700 Subject: Add missing Capybara select2 helper --- spec/support/select2_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/support/select2_helper.rb b/spec/support/select2_helper.rb index 6b1853c2364..515341bc565 100644 --- a/spec/support/select2_helper.rb +++ b/spec/support/select2_helper.rb @@ -11,6 +11,11 @@ # module Select2Helper + def capybara_select2(value) + # Taken from https://github.com/goodwill/capybara-select2/blob/master/gem/lib/capybara-select2.rb#L45 + find('.select2-drop li.select2-result-selectable', text: value).click + end + def select2(value, options = {}) raise ArgumentError, 'options must be a Hash' unless options.is_a?(Hash) -- cgit v1.2.1 From 541a082c9fdfdf8f3999fda894e5e1feb10158a8 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 16 Aug 2017 02:20:39 -0700 Subject: Rename find('.ace_editor') -> find('.ace_text-input') to make Chrome happy --- spec/features/projects/snippets/create_snippet_spec.rb | 2 +- spec/features/snippets/user_creates_snippet_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index 3e79dba3f19..7dc779fa573 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -10,7 +10,7 @@ feature 'Create Snippet', :js do fill_in 'project_snippet_title', with: 'My Snippet Title' fill_in 'project_snippet_description', with: 'My Snippet **Description**' page.within('.file-editor') do - find('.ace_editor').native.send_keys('Hello World!') + find('.ace_text-input').native.send_keys('Hello World!') end end diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index d732383a1e1..0b9ad37f0e9 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -14,7 +14,7 @@ feature 'User creates snippet', :js do fill_in 'personal_snippet_title', with: 'My Snippet Title' fill_in 'personal_snippet_description', with: 'My Snippet **Description**' page.within('.file-editor') do - find('.ace_editor').native.send_keys 'Hello World!' + find('.ace_text-input').native.send_keys 'Hello World!' end end @@ -94,7 +94,7 @@ feature 'User creates snippet', :js do fill_in 'personal_snippet_title', with: 'My Snippet Title' page.within('.file-editor') do find(:xpath, "//input[@id='personal_snippet_file_name']").set 'snippet+file+name' - find('.ace_editor').native.send_keys 'Hello World!' + find('.ace_text-input').native.send_keys 'Hello World!' end click_button 'Create snippet' -- cgit v1.2.1 From 4a4aae7f37619f15988d963c77560e578739ec78 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 21 Aug 2017 14:38:51 -0700 Subject: Bump .gitlab-ci image to use git 2.13 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 376f0a3f2ec..92ed11db240 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-60.0-node-7.1-postgresql-9.6" +image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.13-chrome-60.0-node-7.1-postgresql-9.6" .default-cache: &default-cache key: "ruby-233-with-yarn" -- cgit v1.2.1 From dda33bd76ad1e26aca133f2dc176900d8a64dafa Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 21 Aug 2017 16:07:15 -0700 Subject: Rename JavaScript click -> click() to make karma tests pass --- .../integrations/integration_settings_form_spec.js | 2 +- spec/javascripts/issue_spec.js | 10 +++++----- spec/javascripts/merge_request_notes_spec.js | 2 +- .../pipeline_schedules/setup_pipeline_variable_list_spec.js | 2 +- spec/javascripts/u2f/authenticate_spec.js | 8 ++++---- spec/javascripts/u2f/register_spec.js | 12 ++++++------ 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/spec/javascripts/integrations/integration_settings_form_spec.js b/spec/javascripts/integrations/integration_settings_form_spec.js index 77ade71cc55..57846555261 100644 --- a/spec/javascripts/integrations/integration_settings_form_spec.js +++ b/spec/javascripts/integrations/integration_settings_form_spec.js @@ -168,7 +168,7 @@ describe('IntegrationSettingsForm', () => { expect($flashAction).toBeDefined(); spyOn(integrationSettingsForm.$form, 'submit'); - $flashAction.click; + $flashAction.click(); expect(integrationSettingsForm.$form.submit).toHaveBeenCalled(); }); diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 2c22b4db077..e982f23c87e 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -128,7 +128,7 @@ describe('Issue', function() { }); it(`${action}s the issue`, function() { - this.$triggeredButton.click; + this.$triggeredButton.click(); this.issueStateDeferred.resolve({ id: 34 }); @@ -143,7 +143,7 @@ describe('Issue', function() { }); it(`fails to ${action} the issue if saved:false`, function() { - this.$triggeredButton.click; + this.$triggeredButton.click(); this.issueStateDeferred.resolve({ saved: false }); @@ -159,7 +159,7 @@ describe('Issue', function() { }); it(`fails to ${action} the issue if HTTP error occurs`, function() { - this.$triggeredButton.click; + this.$triggeredButton.click(); this.issueStateDeferred.reject(); this.canCreateBranchDeferred.resolve({ can_create_branch: isIssueInitiallyOpen @@ -173,7 +173,7 @@ describe('Issue', function() { }); it('disables the new branch button if Ajax call fails', function() { - this.$triggeredButton.click; + this.$triggeredButton.click(); this.issueStateDeferred.reject(); this.canCreateBranchDeferred.reject(); @@ -184,7 +184,7 @@ describe('Issue', function() { Issue.$btnNewBranch = $(); this.canCreateBranchDeferred = null; - this.$triggeredButton.click; + this.$triggeredButton.click(); this.issueStateDeferred.reject(); }); }); diff --git a/spec/javascripts/merge_request_notes_spec.js b/spec/javascripts/merge_request_notes_spec.js index f0ec22792d3..7ba754e672a 100644 --- a/spec/javascripts/merge_request_notes_spec.js +++ b/spec/javascripts/merge_request_notes_spec.js @@ -84,7 +84,7 @@ describe('Merge request notes', () => { spyOnEvent('.note:last .js-note-edit', 'click'); - $('.js-discussion-reply-button').click; + $('.js-discussion-reply-button').click(); setTimeout(() => { $('.js-note-text').trigger(upArrowEvent); diff --git a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js index 162a393f6d4..e90c20e20d2 100644 --- a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js +++ b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js @@ -92,7 +92,7 @@ describe('Pipeline Variable List', () => { }); it('should remove the row when clicking the remove button', () => { - $markup.find('.js-row-remove-button').click; + $markup.find('.js-row-remove-button').click(); expect($markup.find('.js-row').length).toBe(0); }); diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js index 037e0aefdf4..e924107b29b 100644 --- a/spec/javascripts/u2f/authenticate_spec.js +++ b/spec/javascripts/u2f/authenticate_spec.js @@ -44,7 +44,7 @@ import './mock_u2f_device'; it("displays an error message", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-login-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToAuthenticateRequest({ errorCode: "error!" }); @@ -54,14 +54,14 @@ import './mock_u2f_device'; return it("allows retrying authentication after an error", function() { var retryButton, setupButton; setupButton = this.container.find("#js-login-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToAuthenticateRequest({ errorCode: "error!" }); retryButton = this.container.find("#js-u2f-try-again"); - retryButton.click; + retryButton.click(); setupButton = this.container.find("#js-login-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToAuthenticateRequest({ deviceData: "this is data from the device" }); diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js index 2c80ac9aa69..f5e32c1b358 100644 --- a/spec/javascripts/u2f/register_spec.js +++ b/spec/javascripts/u2f/register_spec.js @@ -23,7 +23,7 @@ import './mock_u2f_device'; var deviceResponse, inProgressMessage, registeredMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); expect(setupButton.text()).toBe('Setup new U2F device'); - setupButton.click; + setupButton.click(); inProgressMessage = this.container.children("p"); expect(inProgressMessage.text()).toContain("Trying to communicate with your device"); this.u2fDevice.respondToRegisterRequest({ @@ -38,7 +38,7 @@ import './mock_u2f_device'; it("doesn't allow the same device to be registered twice (for the same user", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToRegisterRequest({ errorCode: 4 }); @@ -48,7 +48,7 @@ import './mock_u2f_device'; it("displays an error message for other errors", function() { var errorMessage, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToRegisterRequest({ errorCode: "error!" }); @@ -58,14 +58,14 @@ import './mock_u2f_device'; return it("allows retrying registration after an error", function() { var registeredMessage, retryButton, setupButton; setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToRegisterRequest({ errorCode: "error!" }); retryButton = this.container.find("#U2FTryAgain"); - retryButton.click; + retryButton.click(); setupButton = this.container.find("#js-setup-u2f-device"); - setupButton.click; + setupButton.click(); this.u2fDevice.respondToRegisterRequest({ deviceData: "this is data from the device" }); -- cgit v1.2.1 From 7b79ec07278887e31a34a7a2fae7f1af44b8c8e5 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 21 Aug 2017 21:26:51 -0700 Subject: Fix milestone Spinach tests by confirming modal only if it is present --- features/steps/project/issues/milestones.rb | 3 ++- features/support/capybara_helpers.rb | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 features/support/capybara_helpers.rb diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index fe94eb03acd..d4345a4a432 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -3,6 +3,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps include SharedProject include SharedPaths include SharedMarkdown + include CapybaraHelpers step 'I should see milestone "v2.2"' do milestone = @project.milestones.find_by(title: "v2.2") @@ -63,7 +64,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I click link to remove milestone' do - click_link 'Delete' + confirm_modal_if_present { click_link 'Delete' } end step 'I should see no milestones' do diff --git a/features/support/capybara_helpers.rb b/features/support/capybara_helpers.rb new file mode 100644 index 00000000000..647f8d087c3 --- /dev/null +++ b/features/support/capybara_helpers.rb @@ -0,0 +1,10 @@ +module CapybaraHelpers + def confirm_modal_if_present + if Capybara.current_driver == Capybara.javascript_driver + accept_confirm { yield } + return + end + + yield + end +end -- cgit v1.2.1 From 3e4b7e987668068b716ff4b702db07edcfb0f424 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 22 Aug 2017 05:00:37 -0700 Subject: Use find_link instead of incorrect jQuery to make Selenium test pass --- spec/features/issues/filtered_search/filter_issues_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 2070043d842..1029a5787b8 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -848,7 +848,7 @@ describe 'Filter issues', js: true do it 'updates atom feed link for group issues' do visit issues_group_path(group, milestone_title: milestone.title, assignee_id: user.id) - link = find('.nav-controls a', text: 'Subscribe') + link = find_link('Subscribe') params = CGI.parse(URI.parse(link[:href]).query) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) -- cgit v1.2.1 From 4ab7d2f9401e46185ca90e21019af8f42bb485d7 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 23 Aug 2017 23:29:05 -0700 Subject: Fix branch creation Spinach test by clicking on the dropdown --- features/steps/project/commits/branches.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index 080e59f789b..93f5e291aff 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -79,6 +79,10 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end def select_branch(branch_name) + within('#new-branch-form') do + find('.dropdown').click + end + click_button 'master' page.within '#new-branch-form .dropdown-menu' do -- cgit v1.2.1 From 1899d543a6a18e8aa59abdc19a47d38bbb3cc487 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 23 Aug 2017 23:38:09 -0700 Subject: Change trigger('click') and trigger('mouseover') -> click --- spec/features/merge_requests/diff_notes_avatars_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 09aab8195e1..13721b72584 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -54,7 +54,7 @@ feature 'Diff note avatars', js: true do end it 'does not render avatar after commenting' do - first('.diff-line-num').trigger('mouseover') + first('.diff-line-num').click find('.js-add-diff-note-button').click page.within('.js-discussion-note-form') do @@ -157,7 +157,7 @@ feature 'Diff note avatars', js: true do end page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').trigger('click') + find('.diff-notes-collapse').click expect(page).to have_selector('img.js-diff-comment-avatar', count: 3) expect(find('.diff-comments-more-count')).to have_content '+1' -- cgit v1.2.1 From 07e95212d2b9fe0e96501221fe639cc0d74a7cea Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 23 Aug 2017 23:57:51 -0700 Subject: Fix recent_searches_spec.rb by clicking on buttons instead of relying on hidden elements --- spec/features/issues/filtered_search/recent_searches_spec.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index 4fc1f3209b3..e9cb2850496 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -80,7 +80,8 @@ describe 'Recent searches', js: true do set_recent_searches(project_1_local_storage_key, '["foo", "bar"]') visit project_issues_path(project_1) - all('.filtered-search-history-dropdown-item', visible: false)[0].click + find('.filtered-search-history-dropdown-toggle-button').click + all('.filtered-search-history-dropdown-item')[0].click wait_for_filtered_search('foo') expect(find('.filtered-search').value.strip).to eq('foo') @@ -90,12 +91,14 @@ describe 'Recent searches', js: true do set_recent_searches(project_1_local_storage_key, '["foo"]') visit project_issues_path(project_1) - items_before = all('.filtered-search-history-dropdown-item', visible: false) + find('.filtered-search-history-dropdown-toggle-button').click + items_before = all('.filtered-search-history-dropdown-item') expect(items_before.count).to eq(1) - find('.filtered-search-history-clear-button', visible: false).click - items_after = all('.filtered-search-history-dropdown-item', visible: false) + find('.filtered-search-history-clear-button').click + find('.filtered-search-history-dropdown-toggle-button').click + items_after = all('.filtered-search-history-dropdown-item') expect(items_after.count).to eq(0) end -- cgit v1.2.1 From f2c60eba25fc001974a61373bc380528416932a2 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 26 Aug 2017 00:21:30 -0700 Subject: Fix create branch Spinach spec --- features/steps/project/commits/branches.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index 93f5e291aff..6d019a38fe1 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -79,11 +79,7 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end def select_branch(branch_name) - within('#new-branch-form') do - find('.dropdown').click - end - - click_button 'master' + find('.git-revision-dropdown-toggle').click page.within '#new-branch-form .dropdown-menu' do click_link branch_name -- cgit v1.2.1 From 2d58626a33bc0d4e78eaf0c25965d18a6239fa3b Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 12 Sep 2017 16:43:28 -0500 Subject: Changed helper methods to use the click method --- spec/support/features/reportable_note_shared_examples.rb | 2 +- spec/support/helpers/note_interaction_helpers.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/support/features/reportable_note_shared_examples.rb b/spec/support/features/reportable_note_shared_examples.rb index 192a2fed0a8..836e5e7be23 100644 --- a/spec/support/features/reportable_note_shared_examples.rb +++ b/spec/support/features/reportable_note_shared_examples.rb @@ -39,7 +39,7 @@ shared_examples 'reportable note' do |type| end def open_dropdown(dropdown) - dropdown.find('.more-actions-toggle').trigger('click') + dropdown.find('.more-actions-toggle').click dropdown.find('.dropdown-menu li', match: :first) end end diff --git a/spec/support/helpers/note_interaction_helpers.rb b/spec/support/helpers/note_interaction_helpers.rb index 86008698692..79a0aa174b1 100644 --- a/spec/support/helpers/note_interaction_helpers.rb +++ b/spec/support/helpers/note_interaction_helpers.rb @@ -2,7 +2,7 @@ module NoteInteractionHelpers def open_more_actions_dropdown(note) note_element = find("#note_#{note.id}") - note_element.find('.more-actions-toggle').trigger('click') + note_element.find('.more-actions-toggle').click note_element.find('.more-actions .dropdown-menu li', match: :first) end end -- cgit v1.2.1 From d7b48eb0e94af4648a4cc13bcc789ad66d83dab8 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 19 Sep 2017 12:51:16 -0500 Subject: Replaced trigger calls for click --- spec/features/issues/move_spec.rb | 6 +++--- spec/features/merge_requests/diffs_spec.rb | 2 +- spec/features/search/user_searches_for_wiki_pages_spec.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index b2724945da4..77e04f46b93 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -38,7 +38,7 @@ feature 'issue move to another project' do end scenario 'moving issue to another project', js: true do - find('.js-move-issue').trigger('click') + find('.js-move-issue').click wait_for_requests all('.js-move-issue-dropdown-item')[0].click find('.js-move-issue-confirmation-button').click @@ -52,7 +52,7 @@ feature 'issue move to another project' do scenario 'searching project dropdown', js: true do new_project_search.team << [user, :reporter] - find('.js-move-issue').trigger('click') + find('.js-move-issue').click wait_for_requests page.within '.js-sidebar-move-issue-block' do @@ -69,7 +69,7 @@ feature 'issue move to another project' do background { another_project.team << [user, :guest] } scenario 'browsing projects in projects select' do - find('.js-move-issue').trigger('click') + find('.js-move-issue').click wait_for_requests page.within '.js-sidebar-move-issue-block' do diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index e9068f722d5..a8f5dc275e4 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -88,7 +88,7 @@ feature 'Diffs URL', js: true do visit diffs_project_merge_request_path(project, merge_request) # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax - find("[id=\"#{changelog_id}\"] .js-edit-blob").trigger('click') + find("[id=\"#{changelog_id}\"] .js-edit-blob").click expect(page).to have_selector('.js-fork-suggestion-button', count: 1) expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1) diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb index 1ea56479ecc..00af625dc86 100644 --- a/spec/features/search/user_searches_for_wiki_pages_spec.rb +++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb @@ -15,14 +15,14 @@ describe 'User searches for wiki pages', :js do include_examples 'top right search form' it 'finds a page' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within('.project-filter') do click_link(project.name_with_namespace) end fill_in('dashboard_search', with: 'content') - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Wiki') -- cgit v1.2.1 From d4f3fca93bf31680b7cb23f6e68e809b864b27e8 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 20 Sep 2017 11:09:49 -0500 Subject: fix broken add_cookies --- spec/features/merge_requests/user_posts_diff_notes_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index c298f1927f1..0f31799f083 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -6,7 +6,8 @@ feature 'Merge requests > User posts diff notes', :js do let(:project) { merge_request.source_project } before do - page.driver.set_cookie('sidebar_collapsed', 'true') + visit '/' + page.driver.browser.manage.add_cookie(name: 'sidebar_collapsed', value: 'true') project.add_developer(user) sign_in(user) -- cgit v1.2.1 From 7a8514c3a1806f44d7602c7a6602c116b4264adb Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Fri, 22 Sep 2017 13:15:43 -0500 Subject: add set_cookie helper --- spec/features/boards/boards_spec.rb | 3 ++- .../issues/filtered_search/visual_tokens_spec.rb | 3 ++- spec/features/merge_requests/diff_notes_avatars_spec.rb | 3 ++- .../merge_requests/user_posts_diff_notes_spec.rb | 5 +++-- spec/support/cookie_helper.rb | 17 +++++++++++++++++ 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 spec/support/cookie_helper.rb diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 33aca6cb527..cfff6025459 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' describe 'Issue Boards', js: true do + include CookieHelper include DragTo let(:group) { create(:group, :nested) } @@ -13,7 +14,7 @@ describe 'Issue Boards', js: true do project.team << [user, :master] project.team << [user2, :master] - page.driver.set_cookie('sidebar_collapsed', 'true') + set_cookie('sidebar_collapsed', 'true') sign_in(user) end diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index 2b624f4842d..949def43690 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' describe 'Visual tokens', js: true do + include CookieHelper include FilteredSearchHelpers include WaitForRequests @@ -28,7 +29,7 @@ describe 'Visual tokens', js: true do sign_in(user) create(:issue, project: project) - page.driver.set_cookie('sidebar_collapsed', 'true') + set_cookie('sidebar_collapsed', 'true') visit project_issues_path(project) end diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index ce82c5cd1dc..6f025fdc855 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' feature 'Diff note avatars', js: true do + include CookieHelper include NoteInteractionHelpers let(:user) { create(:user) } @@ -22,7 +23,7 @@ feature 'Diff note avatars', js: true do project.team << [user, :master] sign_in user - page.driver.set_cookie('sidebar_collapsed', 'true') + set_cookie('sidebar_collapsed', 'true') end context 'discussion tab' do diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index 0f31799f083..3b873d6f53c 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -1,13 +1,14 @@ require 'spec_helper' feature 'Merge requests > User posts diff notes', :js do + include CookieHelper + let(:user) { create(:user) } let(:merge_request) { create(:merge_request) } let(:project) { merge_request.source_project } before do - visit '/' - page.driver.browser.manage.add_cookie(name: 'sidebar_collapsed', value: 'true') + set_cookie('sidebar_collapsed', 'true') project.add_developer(user) sign_in(user) diff --git a/spec/support/cookie_helper.rb b/spec/support/cookie_helper.rb new file mode 100644 index 00000000000..224619c899c --- /dev/null +++ b/spec/support/cookie_helper.rb @@ -0,0 +1,17 @@ +# Helper for setting cookies in Selenium/WebDriver +# +module CookieHelper + def set_cookie(name, value, options = {}) + # Selenium driver will not set cookies for a given domain when the browser is at `about:blank`. + # It also doesn't appear to allow overriding the cookie path. loading `/` is the most inclusive. + visit options.fetch(:path, '/') unless on_a_page? + page.driver.browser.manage.add_cookie(name: name, value: value, **options) + end + + private + + def on_a_page? + current_url = Capybara.current_session.driver.browser.current_url + current_url && current_url != '' && current_url != 'about:blank' && current_url != 'data:,' + end +end -- cgit v1.2.1 From bea18efad3f1ea0462d57f53984df8e98cdb4636 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 25 Sep 2017 11:14:19 -0500 Subject: Replaced trigger calls for click --- spec/features/projects/members/share_with_group_spec.rb | 4 ++-- spec/features/projects/wiki/user_views_wiki_page_spec.rb | 2 +- spec/features/search/user_searches_for_code_spec.rb | 4 ++-- spec/features/search/user_searches_for_issues_spec.rb | 8 ++++---- spec/features/search/user_searches_for_merge_requests_spec.rb | 6 +++--- spec/features/search/user_searches_for_milestones_spec.rb | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/features/projects/members/share_with_group_spec.rb b/spec/features/projects/members/share_with_group_spec.rb index 3b368f8e25d..a52fc316474 100644 --- a/spec/features/projects/members/share_with_group_spec.rb +++ b/spec/features/projects/members/share_with_group_spec.rb @@ -41,7 +41,7 @@ feature 'Project > Members > Share with Group', :js do select2 group_to_share_with.id, from: '#link_group_id' page.find('body').click - find('.btn-create').trigger('click') + find('.btn-create').click page.within('.project-members-groups') do expect(page).to have_content(group_to_share_with.name) @@ -123,7 +123,7 @@ feature 'Project > Members > Share with Group', :js do fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d') page.find('body').click - find('.btn-create').trigger('click') + find('.btn-create').click end scenario 'the group link shows the expiration time with a warning class' do diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb index d201d4f6b98..9790337985d 100644 --- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb @@ -133,7 +133,7 @@ describe 'User views a wiki page' do it 'opens a default wiki page', :js do visit(project_path(project)) - find('.shortcuts-wiki').trigger('click') + find('.shortcuts-wiki').click expect(page).to have_content('Home · Create Page') end diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb index 0ed797a62ea..77212fb105b 100644 --- a/spec/features/search/user_searches_for_code_spec.rb +++ b/spec/features/search/user_searches_for_code_spec.rb @@ -32,14 +32,14 @@ describe 'User searches for code' do include_examples 'top right search form' it 'finds code' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within('.project-filter') do click_link(project.name_with_namespace) end fill_in('dashboard_search', with: 'rspec') - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.results') do expect(find(:css, '.search-results')).to have_content('Update capybara, rspec-rails, poltergeist to recent versions') diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb index 630a81b1c5e..ef9553f2a91 100644 --- a/spec/features/search/user_searches_for_issues_spec.rb +++ b/spec/features/search/user_searches_for_issues_spec.rb @@ -18,7 +18,7 @@ describe 'User searches for issues', :js do it 'finds an issue' do fill_in('dashboard_search', with: issue1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Issues') @@ -31,14 +31,14 @@ describe 'User searches for issues', :js do context 'when on a project page' do it 'finds an issue' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within('.project-filter') do click_link(project.name_with_namespace) end fill_in('dashboard_search', with: issue1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Issues') @@ -62,7 +62,7 @@ describe 'User searches for issues', :js do it 'finds an issue' do fill_in('dashboard_search', with: issue1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Issues') diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb index 116256682f4..3b6739aecbd 100644 --- a/spec/features/search/user_searches_for_merge_requests_spec.rb +++ b/spec/features/search/user_searches_for_merge_requests_spec.rb @@ -17,7 +17,7 @@ describe 'User searches for merge requests', :js do it 'finds a merge request' do fill_in('dashboard_search', with: merge_request1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Merge requests') @@ -30,14 +30,14 @@ describe 'User searches for merge requests', :js do context 'when on a project page' do it 'finds a merge request' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within('.project-filter') do click_link(project.name_with_namespace) end fill_in('dashboard_search', with: merge_request1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Merge requests') diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb index 4fa9fe9ce8c..6e197aee498 100644 --- a/spec/features/search/user_searches_for_milestones_spec.rb +++ b/spec/features/search/user_searches_for_milestones_spec.rb @@ -17,7 +17,7 @@ describe 'User searches for milestones', :js do it 'finds a milestone' do fill_in('dashboard_search', with: milestone1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Milestones') @@ -30,14 +30,14 @@ describe 'User searches for milestones', :js do context 'when on a project page' do it 'finds a milestone' do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click page.within('.project-filter') do click_link(project.name_with_namespace) end fill_in('dashboard_search', with: milestone1.title) - find('.btn-search').trigger('click') + find('.btn-search').click page.within('.search-filter') do click_link('Milestones') -- cgit v1.2.1 From 299213dd01b959b82952284194ea844c33b5a691 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 26 Sep 2017 10:30:26 -0500 Subject: Replaced trigger calls for click, fixed click_on call --- spec/features/projects/features_visibility_spec.rb | 4 ++-- spec/features/search/user_uses_search_filters_spec.rb | 6 +++--- spec/features/snippets/notes_on_personal_snippets_spec.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 57722276d79..e05b1ce225a 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -22,7 +22,7 @@ describe 'Edit Project Settings' do # disable by clicking toggle toggle_feature_off("project[project_feature_attributes][#{tool_name}_access_level]") page.within('.sharing-permissions') do - click_button 'Save changes' + find('input[value="Save changes"]').click end wait_for_requests expect(page).not_to have_selector(".shortcuts-#{shortcut_name}") @@ -30,7 +30,7 @@ describe 'Edit Project Settings' do # re-enable by clicking toggle again toggle_feature_on("project[project_feature_attributes][#{tool_name}_access_level]") page.within('.sharing-permissions') do - click_button 'Save changes' + find('input[value="Save changes"]').click end wait_for_requests expect(page).to have_selector(".shortcuts-#{shortcut_name}") diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb index 95f3eb5e805..aa883c964d2 100644 --- a/spec/features/search/user_uses_search_filters_spec.rb +++ b/spec/features/search/user_uses_search_filters_spec.rb @@ -16,7 +16,7 @@ describe 'User uses search filters', :js do context' when filtering by group' do it 'shows group projects' do - find('.js-search-group-dropdown').trigger('click') + find('.js-search-group-dropdown').click wait_for_requests @@ -27,7 +27,7 @@ describe 'User uses search filters', :js do expect(find('.js-search-group-dropdown')).to have_content(group.name) page.within('.project-filter') do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click wait_for_requests @@ -39,7 +39,7 @@ describe 'User uses search filters', :js do context' when filtering by project' do it 'shows a project' do page.within('.project-filter') do - find('.js-search-project-dropdown').trigger('click') + find('.js-search-project-dropdown').click wait_for_requests diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index e842af39376..d089fb5b730 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -88,7 +88,7 @@ describe 'Comments on personal snippets', :js do context 'when editing a note' do it 'changes the text' do - find('.js-note-edit').trigger('click') + find('.js-note-edit').click page.within('.current-note-edit-form') do fill_in 'note[note]', with: 'new content' -- cgit v1.2.1 From 7fb477325eb7f1215a6ae128c9a3a300606d7fbe Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 26 Sep 2017 12:11:22 -0500 Subject: fixed users_spec --- spec/features/users_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index 15b89dac572..bf1dd7cc073 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -24,6 +24,7 @@ feature 'Users', js: true do user.reload expect(user.reset_password_token).not_to be_nil + find('a[href="#login-pane"]').click gitlab_sign_in(user) expect(current_path).to eq root_path -- cgit v1.2.1 From c01338cba55ae6e32c4f8801d727e4c2c52ec1c9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 11:10:58 +0100 Subject: fixed spec/features/u2f_spec.rb a lot of failures where because everything happens faster than rspec can detect on the page --- spec/features/u2f_spec.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 915d90859ba..8178e4144f1 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -191,7 +191,6 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Try authenticating user with the old U2F device gitlab_sign_in(current_user) @u2f_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_content('Authentication via U2F device failed') end end @@ -209,7 +208,6 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Try authenticating user with the same U2F device gitlab_sign_in(current_user) @u2f_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_css('.sign-out-link', visible: false) end @@ -221,7 +219,6 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do unregistered_device = FakeU2fDevice.new(page, 'My device') gitlab_sign_in(user) unregistered_device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_content('Authentication via U2F device failed') end @@ -246,7 +243,6 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do [first_device, second_device].each do |device| gitlab_sign_in(user) device.respond_to_u2f_authentication - expect(page).to have_content('We heard back from your U2F device') expect(page).to have_css('.sign-out-link', visible: false) @@ -269,7 +265,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it "deletes u2f registrations" do visit profile_account_path - expect { click_on "Disable" }.to change { U2fRegistration.count }.by(-1) + expect do + accept_confirm { click_on "Disable" } + end.to change{ U2fRegistration.count }.by(-1) end end end -- cgit v1.2.1 From 54a6bcae954c08c890c66452d7d34d5393227e7d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:08:31 +0100 Subject: fixed spec/features/projects/files/edit_file_soft_wrap_spec.rb --- .../projects/files/edit_file_soft_wrap_spec.rb | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index c7e3f657639..5639be19364 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -7,18 +7,18 @@ feature 'User uses soft wrap whilst editing file', js: true do project.team << [user, :master] sign_in user visit project_new_blob_path(project, 'master', file_name: 'test_file-name') - editor = find('.file-editor.code') - editor.click - editor.send_keys 'Touch water with paw then recoil in horror chase dog then - run away chase the pig around the house eat owner\'s food, and knock - dish off table head butt cant eat out of my own dish. Cat is love, cat - is life rub face on everything poop on grasses so meow. Playing with - balls of wool flee in terror at cucumber discovered on floor run in - circles tuxedo cats always looking dapper, but attack dog, run away - and pretend to be victim so all of a sudden cat goes crazy, yet chase - laser. Make muffins sit in window and stare ooo, a bird! yum lick yarn - hanging out of own butt jump off balcony, onto stranger\'s head yet - chase laser. Purr for no reason stare at ceiling hola te quiero.'.squish + page.within('.file-editor.code') do + find('.ace_text-input', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then + run away chase the pig around the house eat owner\'s food, and knock + dish off table head butt cant eat out of my own dish. Cat is love, cat + is life rub face on everything poop on grasses so meow. Playing with + balls of wool flee in terror at cucumber discovered on floor run in + circles tuxedo cats always looking dapper, but attack dog, run away + and pretend to be victim so all of a sudden cat goes crazy, yet chase + laser. Make muffins sit in window and stare ooo, a bird! yum lick yarn + hanging out of own butt jump off balcony, onto stranger\'s head yet + chase laser. Purr for no reason stare at ceiling hola te quiero.'.squish + end end let(:toggle_button) { find('.soft-wrap-toggle') } @@ -36,6 +36,6 @@ feature 'User uses soft wrap whilst editing file', js: true do end def get_content_width - find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/) + find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/).to_i end end -- cgit v1.2.1 From d770b633ebcf3b5378031af6e02aebf1a75b8468 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:23:38 +0100 Subject: fixed spec/features/projects/settings/repository_settings_spec.rb --- spec/features/projects/settings/repository_settings_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 15180d4b498..3caf68dced4 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -34,7 +34,6 @@ feature 'Repository settings' do visit project_settings_repository_path(project) - expect(page.status_code).to eq(200) expect(page).to have_content('private_deploy_key') expect(page).to have_content('public_deploy_key') end @@ -86,7 +85,7 @@ feature 'Repository settings' do project.deploy_keys << private_deploy_key visit project_settings_repository_path(project) - find('li', text: private_deploy_key.title).click_button('Remove') + accept_confirm { find('li', text: private_deploy_key.title).click_button('Remove') } expect(page).not_to have_content(private_deploy_key.title) end -- cgit v1.2.1 From 92a3887c9a2977881c63a8e9eb9b85c1361f3d2d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:28:34 +0100 Subject: fixed spec/features/issues/filtered_search/dropdown_assignee_spec.rb spec runs too fast so it doesn't match the first text. I think testing that the loading indicator is hidden is enough --- spec/features/issues/filtered_search/dropdown_assignee_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 1c4649d0ba9..550a778bda1 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -51,7 +51,6 @@ describe 'Dropdown assignee', :js do it 'should hide loading indicator when loaded' do filtered_search.set('assignee:') - expect(find(js_dropdown_assignee)).to have_css('.filter-dropdown-loading') expect(find(js_dropdown_assignee)).not_to have_css('.filter-dropdown-loading') end -- cgit v1.2.1 From 9d48177c8e43a338e72d07d1fd92805f8e3313b4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:34:41 +0100 Subject: fixed spec/features/admin/admin_users_spec.rb --- spec/features/admin/admin_users_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index e2e2b13cf8a..a4a9516a3e4 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -290,7 +290,7 @@ describe "Admin::Users" do it 'allows group membership to be revoked', js: true do page.within(first('.group_member')) do - find('.btn-remove').click + accept_confirm { find('.btn-remove').click } end wait_for_requests @@ -319,7 +319,7 @@ describe "Admin::Users" do expect(page).to have_content("Secondary email: #{secondary_email.email}") - find("#remove_email_#{secondary_email.id}").click + accept_confirm { find("#remove_email_#{secondary_email.id}").click } expect(page).not_to have_content(secondary_email.email) end -- cgit v1.2.1 From 7a090d59a347aa1daf44a20e0fba327bf47b0dce Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:36:05 +0100 Subject: fixed spec/features/admin/admin_groups_spec.rb --- spec/features/admin/admin_groups_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 3768727d8ae..cddd8d2a166 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -152,7 +152,7 @@ feature 'Admin Groups' do expect(page).to have_content('Developer') end - find(:css, 'li', text: current_user.name).find(:css, 'a.btn-remove').click + accept_confirm { find(:css, 'li', text: current_user.name).find(:css, 'a.btn-remove').click } visit group_group_members_path(group) -- cgit v1.2.1 From 27c00d2ed39eca9543502427380abc46ed7a8193 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:40:24 +0100 Subject: fixed spec/features/dashboard/groups_list_spec.rb --- spec/features/dashboard/groups_list_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index bb4f3d9ecb4..4c120b09345 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -74,14 +74,14 @@ feature 'Dashboard Groups page', :js do expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right") # Collapse - find("#group-#{group.id}").click + find("#group-#{group.id} .folder-caret").click expect(page).not_to have_selector("#group-#{group.id} .fa-caret-down") expect(page).to have_selector("#group-#{group.id} .fa-caret-right", count: 1) expect(page).not_to have_selector("#group-#{group.id} #group-#{subgroup.id}") # Expand - find("#group-#{group.id}").click + find("#group-#{group.id} .folder-caret").click expect(page).to have_selector("#group-#{group.id} .fa-caret-down", count: 1) expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right") -- cgit v1.2.1 From 1ec2486c83c55042caf1f8006187f6abde0056a4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 12:50:38 +0100 Subject: fixed spec/features/projects/deploy_keys_spec.rb --- spec/features/projects/deploy_keys_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb index 2d1a9b931b5..1c1c25c932e 100644 --- a/spec/features/projects/deploy_keys_spec.rb +++ b/spec/features/projects/deploy_keys_spec.rb @@ -20,7 +20,7 @@ describe 'Project deploy keys', :js do page.within(find('.deploy-keys')) do expect(page).to have_selector('.deploy-keys li', count: 1) - click_on 'Remove' + accept_confirm { find(:button, text: 'Remove').click } expect(page).not_to have_selector('.fa-spinner', count: 0) expect(page).to have_selector('.deploy-keys li', count: 0) -- cgit v1.2.1 From 15b976c6141424d891e304d13be0a126c5e1265b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 13:34:30 +0100 Subject: some fixes in spec/features/projects/jobs_spec.rb not sure how to fix the ones with headers :thinking: --- spec/features/projects/jobs_spec.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 4848159c1f7..a0d36203366 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -380,7 +380,6 @@ feature 'Jobs' do end it 'loads the page and shows all needed controls' do - expect(page.status_code).to eq(200) expect(page).to have_content 'Retry' end end @@ -396,7 +395,6 @@ feature 'Jobs' do end it 'shows the right status and buttons', :js do - expect(page).to have_http_status(200) page.within('aside.right-sidebar') do expect(page).to have_content 'Cancel' end @@ -450,7 +448,6 @@ feature 'Jobs' do end it 'sends the right headers' do - expect(page.status_code).to eq(200) expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') expect(page.response_headers['X-Sendfile']).to eq(job.trace.send(:current_path)) end @@ -490,7 +487,6 @@ feature 'Jobs' do end it 'sends the right headers' do - expect(page.status_code).to eq(200) expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') expect(page.response_headers['X-Sendfile']).to eq(existing_file) end -- cgit v1.2.1 From 4a6133620779e997b1e3759f68ecfd7fddc4af2f Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 13:36:08 +0100 Subject: fixed spec/features/issues/filtered_search/dropdown_milestone_spec.rb --- spec/features/issues/filtered_search/dropdown_milestone_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index f6c2e952bea..8536686e611 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -58,7 +58,6 @@ describe 'Dropdown milestone', :js do it 'should hide loading indicator when loaded' do filtered_search.set('milestone:') - expect(find(js_dropdown_milestone)).to have_css('.filter-dropdown-loading') expect(find(js_dropdown_milestone)).not_to have_css('.filter-dropdown-loading') end -- cgit v1.2.1 From d2561680d04e18669f08182d3d03512d99310c97 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 13:43:44 +0100 Subject: fixed spec/features/merge_requests/versions_spec.rb --- spec/features/merge_requests/versions_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 6669522dd7a..1de277fe4f9 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -67,7 +67,7 @@ feature 'Merge Request versions', js: true do line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_2_2' page.within(diff_file_selector) do - find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover' + find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").hover find(".line_holder[id='#{line_code}'] button").click page.within("form[data-line-code='#{line_code}']") do @@ -137,7 +137,7 @@ feature 'Merge Request versions', js: true do line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_4_4' page.within(diff_file_selector) do - find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover' + find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").hover find(".line_holder[id='#{line_code}'] button").click page.within("form[data-line-code='#{line_code}']") do -- cgit v1.2.1 From 45da02f9abb0406130e7c3b6a480fa847e4e6ad9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 27 Sep 2017 13:46:48 +0100 Subject: fixed spec/features/merge_requests/user_posts_notes_spec.rb --- spec/features/merge_requests/user_posts_notes_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb index d7cda73ab40..f4c75a2f265 100644 --- a/spec/features/merge_requests/user_posts_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_notes_spec.rb @@ -141,7 +141,7 @@ describe 'Merge requests > User posts notes', :js do end it 'removes the attachment div and resets the edit form' do - find('.js-note-attachment-delete').click + accept_confirm { find('.js-note-attachment-delete').click } is_expected.not_to have_css('.note-attachment') is_expected.not_to have_css('.current-note-edit-form') wait_for_requests -- cgit v1.2.1 From 5072ecc67b8f20cfa9f212883674c732d3ea8dd6 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Wed, 27 Sep 2017 13:13:07 -0500 Subject: Replaced trigger click calls for click, also fixed ace_editor-input test --- spec/features/issues/update_issues_spec.rb | 2 +- spec/features/merge_requests/update_merge_requests_spec.rb | 2 +- spec/features/snippets/user_creates_snippet_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index 1f57c110c11..bcc6e9bab0f 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -118,7 +118,7 @@ feature 'Multiple issue updating from issues#index', :js do end def click_update_issues_button - find('.update-selected-issues').trigger('click') + find('.update-selected-issues').click wait_for_requests end end diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb index 9cb8a357309..e6dc284cba7 100644 --- a/spec/features/merge_requests/update_merge_requests_spec.rb +++ b/spec/features/merge_requests/update_merge_requests_spec.rb @@ -127,7 +127,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do end def click_update_merge_requests_button - find('.update-selected-issues').trigger('click') + find('.update-selected-issues').click wait_for_requests end end diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index 0b9ad37f0e9..1c73b86c5fb 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -14,7 +14,7 @@ feature 'User creates snippet', :js do fill_in 'personal_snippet_title', with: 'My Snippet Title' fill_in 'personal_snippet_description', with: 'My Snippet **Description**' page.within('.file-editor') do - find('.ace_text-input').native.send_keys 'Hello World!' + find('.ace_text-input', visible: false).send_keys 'Hello World!' end end @@ -94,7 +94,7 @@ feature 'User creates snippet', :js do fill_in 'personal_snippet_title', with: 'My Snippet Title' page.within('.file-editor') do find(:xpath, "//input[@id='personal_snippet_file_name']").set 'snippet+file+name' - find('.ace_text-input').native.send_keys 'Hello World!' + find('.ace_text-input', visible: false).send_keys 'Hello World!' end click_button 'Create snippet' -- cgit v1.2.1 From 06d41721e6d229a87459ad9578534b4a5caefeda Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Fri, 29 Sep 2017 13:06:38 -0500 Subject: modified clear_browser_session method to use the manage method for deleting cookies --- spec/support/capybara_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb index 0106b4e656a..868233416bf 100644 --- a/spec/support/capybara_helpers.rb +++ b/spec/support/capybara_helpers.rb @@ -38,7 +38,7 @@ module CapybaraHelpers # Simulate a browser restart by clearing the session cookie. def clear_browser_session - page.driver.delete_cookie('_gitlab_session') + page.driver.browser.manage.delete_cookie('_gitlab_session') end end -- cgit v1.2.1 From b452b0c7056e481778bfc5838d47dca813bf12ed Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Fri, 29 Sep 2017 13:07:04 -0500 Subject: Used send_keys(:return) for elements that are not clickable at one point --- .../projects/import_export/namespace_export_file_spec.rb | 2 +- spec/features/triggers_spec.rb | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/spec/features/projects/import_export/namespace_export_file_spec.rb b/spec/features/projects/import_export/namespace_export_file_spec.rb index 691b0e1e4ca..23b5febf243 100644 --- a/spec/features/projects/import_export/namespace_export_file_spec.rb +++ b/spec/features/projects/import_export/namespace_export_file_spec.rb @@ -52,7 +52,7 @@ feature 'Import/Export - Namespace export file cleanup', js: true do expect(page).to have_content('Export project') - click_link 'Export project' + find(:link, 'Export project').send_keys(:return) visit edit_project_path(project) diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 477798e3826..a6ec1a1a96a 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -45,7 +45,7 @@ feature 'Triggers', js: true do visit project_settings_ci_cd_path(@project) # See if edit page has correct descrption - find('a[title="Edit"]').click + find('a[title="Edit"]').send_keys(:return) expect(page.find('#trigger_description').value).to have_content 'trigger desc' end @@ -54,7 +54,7 @@ feature 'Triggers', js: true do visit project_settings_ci_cd_path(@project) # See if edit page opens, then fill in new description and save - find('a[title="Edit"]').click + find('a[title="Edit"]').send_keys(:return) fill_in 'trigger_description', with: new_trigger_title click_button 'Save trigger' @@ -70,7 +70,7 @@ feature 'Triggers', js: true do visit project_settings_ci_cd_path(@project) # See if the trigger can be edited and description is blank - find('a[title="Edit"]').click + find('a[title="Edit"]').send_keys(:return) expect(page.find('#trigger_description').value).to have_content '' # See if trigger can be updated with description and saved successfully @@ -95,7 +95,7 @@ feature 'Triggers', js: true do scenario 'take trigger ownership' do # See if "Take ownership" on trigger works post trigger creation page.accept_confirm do - find('a.btn-trigger-take-ownership').click + first(:link, "Take ownership").send_keys(:return) end expect(page.find('.flash-notice')).to have_content 'Trigger was re-assigned.' @@ -117,11 +117,12 @@ feature 'Triggers', js: true do scenario 'revoke trigger' do # See if "Revoke" on trigger works post trigger creation - find('a.btn-trigger-revoke').click page.accept_confirm do - expect(page.find('.flash-notice')).to have_content 'Trigger removed' - expect(page).to have_selector('p.settings-message.text-center.append-bottom-default') + find('a.btn-trigger-revoke').send_keys(:return) end + + expect(page.find('.flash-notice')).to have_content 'Trigger removed' + expect(page).to have_selector('p.settings-message.text-center.append-bottom-default') end end -- cgit v1.2.1 From 7a5c2d5eff6cd13f6971140294c395e877eafacf Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 2 Oct 2017 12:51:16 -0500 Subject: Fix Element is not clickable at this point --- spec/features/issues/bulk_assignment_labels_spec.rb | 2 +- spec/features/merge_requests/conflicts_spec.rb | 6 +++--- spec/features/merge_requests/diff_notes_avatars_spec.rb | 14 +++++++------- .../projects/settings/merge_requests_settings_spec.rb | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index a89dcdf41dc..2cf32e492a0 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -405,7 +405,7 @@ feature 'Issues > Labels bulk assignment' do end def update_issues - find('.update-selected-issues').trigger('click') + find('.update-selected-issues').send_keys(:return) wait_for_requests end diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 70937666334..5e6220c5b1c 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -23,11 +23,11 @@ feature 'Merge request conflict resolution', js: true do within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do all('button', text: 'Use ours').each do |button| - button.click + button.send_keys(:return) end end - click_button 'Commit conflict resolution' + find_button('Commit conflict resolution').send_keys(:return) expect(page).to have_content('All merge conflicts were resolved') merge_request.reload_diff @@ -69,7 +69,7 @@ feature 'Merge request conflict resolution', js: true do execute_script('ace.edit($(".files-wrapper .diff-file pre")[1]).setValue("Gregor Samsa woke from troubled dreams");') end - click_button 'Commit conflict resolution' + find_button('Commit conflict resolution').send_keys(:return) expect(page).to have_content('All merge conflicts were resolved') merge_request.reload_diff diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 6f025fdc855..362a526db0d 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -86,7 +86,7 @@ feature 'Diff note avatars', js: true do it 'shows note avatar' do page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').click + find('.diff-notes-collapse').send_keys(:return) expect(page).to have_selector('img.js-diff-comment-avatar', count: 1) end @@ -94,7 +94,7 @@ feature 'Diff note avatars', js: true do it 'shows comment on note avatar' do page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').click + find('.diff-notes-collapse').send_keys(:return) expect(first('img.js-diff-comment-avatar')["data-original-title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}") end @@ -102,13 +102,13 @@ feature 'Diff note avatars', js: true do it 'toggles comments when clicking avatar' do page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').click + find('.diff-notes-collapse').send_keys(:return) end expect(page).to have_selector('.notes_holder', visible: false) page.within find("[id='#{position.line_code(project.repository)}']") do - first('img.js-diff-comment-avatar').click + first('img.js-diff-comment-avatar').send_keys(:return) end expect(page).to have_selector('.notes_holder') @@ -140,7 +140,7 @@ feature 'Diff note avatars', js: true do end page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').trigger('click') + find('.diff-notes-collapse').send_keys(:return) expect(page).to have_selector('img.js-diff-comment-avatar', count: 2) end @@ -160,7 +160,7 @@ feature 'Diff note avatars', js: true do end page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').click + find('.diff-notes-collapse').send_keys(:return) expect(page).to have_selector('img.js-diff-comment-avatar', count: 3) expect(find('.diff-comments-more-count')).to have_content '+1' @@ -178,7 +178,7 @@ feature 'Diff note avatars', js: true do it 'shows extra comment count' do page.within find("[id='#{position.line_code(project.repository)}']") do - find('.diff-notes-collapse').click + find('.diff-notes-collapse').send_keys(:return) expect(find('.diff-comments-more-count')).to have_content '+1' end diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb index b1ec556bf16..ac76c30cc7c 100644 --- a/spec/features/projects/settings/merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/merge_requests_settings_spec.rb @@ -21,7 +21,7 @@ feature 'Project settings > Merge Requests', :js do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click - click_on('Save changes') + find('input[value="Save changes"]').send_keys(:return) end expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds') @@ -41,7 +41,7 @@ feature 'Project settings > Merge Requests', :js do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][builds_access_level]"] .project-feature-toggle').click - click_on('Save changes') + find('input[value="Save changes"]').send_keys(:return) end expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds') @@ -62,7 +62,7 @@ feature 'Project settings > Merge Requests', :js do within('.sharing-permissions-form') do find('.project-feature-controls[data-for="project[project_feature_attributes][merge_requests_access_level]"] .project-feature-toggle').click - click_on('Save changes') + find('input[value="Save changes"]').send_keys(:return) end expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds') -- cgit v1.2.1 From bea4b0a8df71cd134077580abc5c63fd9767da53 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:02:48 -0500 Subject: fix admin_hooks_spec --- spec/features/admin/admin_hooks_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index 91f08dbad5d..5140889b4c6 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -62,14 +62,14 @@ describe 'Admin::Hooks', :js do it 'from hooks list page' do visit admin_hooks_path - expect { click_link 'Remove' }.to change(SystemHook, :count).by(-1) + expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1) end it 'from hook edit page' do visit admin_hooks_path click_link 'Edit' - expect { click_link 'Remove' }.to change(SystemHook, :count).by(-1) + expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1) end end end -- cgit v1.2.1 From ac417cb39fd9f5d85f75740c9b0ae03026d6d640 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:05:57 -0500 Subject: fix admin_uses_repository_checks --- spec/features/admin/admin_uses_repository_checks_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index c2b7543a690..9f6d6d84081 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -37,7 +37,7 @@ feature 'Admin uses repository checks' do expect(RepositoryCheck::ClearWorker).to receive(:perform_async) - click_link 'Clear all repository checks' + accept_confirm { find(:link, 'Clear all repository checks').send_keys(:return) } expect(page).to have_content('Started asynchronous removal of all repository check states.') end -- cgit v1.2.1 From ebddd8d4801d734190d1dd26e94834208b585260 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:06:21 -0500 Subject: fix diff_notes_spec --- spec/features/projects/commit/diff_notes_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/commit/diff_notes_spec.rb b/spec/features/projects/commit/diff_notes_spec.rb index f0fe4e00acc..4dbfc6f6edf 100644 --- a/spec/features/projects/commit/diff_notes_spec.rb +++ b/spec/features/projects/commit/diff_notes_spec.rb @@ -20,8 +20,8 @@ feature 'Commit diff', :js do it "adds comment to diff" do diff_line_num = first('.diff-line-num.new') - diff_line_num.trigger('mouseover') - diff_line_num.find('.js-add-diff-note-button').trigger('click') + diff_line_num.hover + diff_line_num.find('.js-add-diff-note-button').click page.within(first('.diff-viewer')) do find('.js-note-text').set 'test comment' -- cgit v1.2.1 From 6c541edaf163fbf23859cf7c5fa3d609f3233216 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:06:38 -0500 Subject: fix spec/features/projects/import_export/export_file_spec.rb --- spec/features/projects/deploy_keys_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb index 1c1c25c932e..e445758cb5e 100644 --- a/spec/features/projects/deploy_keys_spec.rb +++ b/spec/features/projects/deploy_keys_spec.rb @@ -20,7 +20,7 @@ describe 'Project deploy keys', :js do page.within(find('.deploy-keys')) do expect(page).to have_selector('.deploy-keys li', count: 1) - accept_confirm { find(:button, text: 'Remove').click } + accept_confirm { find(:button, text: 'Remove').send_keys(:return) } expect(page).not_to have_selector('.fa-spinner', count: 0) expect(page).to have_selector('.deploy-keys li', count: 0) -- cgit v1.2.1 From c3d03582aab57c13644497edbbf07bc5328900be Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:07:19 -0500 Subject: fix export_file_spec --- spec/features/projects/import_export/export_file_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 62d244ff259..30ed023e0c4 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -41,7 +41,7 @@ feature 'Import/Export - project export integration test', js: true do expect(page).to have_content('Export project') - click_link 'Export project' + find(:link, 'Export project').send_keys(:return) visit edit_project_path(project) -- cgit v1.2.1 From 62364576bc4e2b141752a6ea9068171fa619a6ff Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 3 Oct 2017 12:07:44 -0500 Subject: fix mattermost_slash_commands --- .../services/user_activates_mattermost_slash_command_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb index 95d5e8b14b9..6f057137867 100644 --- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb @@ -76,7 +76,7 @@ feature 'Setup Mattermost slash commands', :js do select_element = find('#mattermost_team_id') selected_option = select_element.find('option[selected]') - expect(select_element['disabled']).to be(true) + expect(select_element['disabled']).to eq("true") expect(selected_option).to have_content(team_name.to_s) end @@ -104,7 +104,7 @@ feature 'Setup Mattermost slash commands', :js do select_element = find('#mattermost_team_id') - expect(select_element['disabled']).to be(false) + expect(select_element['disabled']).to be_falsey expect(select_element.all('option').count).to eq(3) end @@ -122,7 +122,7 @@ feature 'Setup Mattermost slash commands', :js do click_link 'Add to Mattermost' - expect(find('input[type="submit"]')['disabled']).not_to be(true) + expect(find('input[type="submit"]')['disabled']).not_to eq("true") end it 'disables the submit button if the required fields are not provided', :js do @@ -132,7 +132,7 @@ feature 'Setup Mattermost slash commands', :js do fill_in('mattermost_trigger', with: '') - expect(find('input[type="submit"]')['disabled']).to be(true) + expect(find('input[type="submit"]')['disabled']).to eq("true") end def stub_teams(count: 0) -- cgit v1.2.1 From a1b3cd40647e8f7768b6db0bc64179e60f5d5937 Mon Sep 17 00:00:00 2001 From: Mircea Danila Dumitrescu Date: Mon, 2 Oct 2017 20:32:36 +0000 Subject: namespace should be lowercased in kubernetes. This is also true for the scenario where the namespace is generated from the project group-name. --- app/models/project_services/kubernetes_service.rb | 12 +++++++++++- changelogs/unreleased/mr-14642.yml | 6 ++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/mr-14642.yml diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index 8ba07173c74..45a544e3674 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -153,7 +153,17 @@ class KubernetesService < DeploymentService end def default_namespace - "#{project.path}-#{project.id}" if project.present? + return unless project + + # 1. lowercase + # 2. replace non kubernetes characters with dash + # 3. trim dash from the beginning and end + + slugified = "#{project.path}-#{project.id}" + slugified.downcase! + slugified.gsub!(/[^a-z0-9]/, '-') + slugified.gsub!(/^-+|-+$/, '') + slugified end def build_kubeclient!(api_path: 'api', api_version: 'v1') diff --git a/changelogs/unreleased/mr-14642.yml b/changelogs/unreleased/mr-14642.yml new file mode 100644 index 00000000000..048cc79e323 --- /dev/null +++ b/changelogs/unreleased/mr-14642.yml @@ -0,0 +1,6 @@ +--- +title: Auto Devops kubernetes default namespace is now correctly built out of gitlab + project group-name +merge_request: 14642 +author: Mircea Danila Dumitrescu +type: fixed -- cgit v1.2.1 From 5abcedf47c375c94b859c294ffb1a9669512a041 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Wed, 4 Oct 2017 13:54:34 -0500 Subject: fix rubocop --- spec/features/u2f_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 8178e4144f1..c9afef2a8de 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -267,7 +267,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do visit profile_account_path expect do accept_confirm { click_on "Disable" } - end.to change{ U2fRegistration.count }.by(-1) + end.to change { U2fRegistration.count }.by(-1) end end end -- cgit v1.2.1 From 10c70b19d0209fcf542dd03a0484d98b6a06ddd3 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Wed, 4 Oct 2017 16:52:06 -0500 Subject: fix admin_settings_spec --- spec/features/admin/admin_settings_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index c490dce7ab0..0a75e07e59d 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -73,7 +73,7 @@ feature 'Admin updates settings' do context 'sign-in restrictions', :js do it 'de-activates oauth sign-in source' do - find('.btn', text: 'GitLab.com').click + find('input#application_setting_enabled_oauth_sign_in_sources_[value=gitlab]').send_keys(:return) expect(find('.btn', text: 'GitLab.com')).not_to have_css('.active') end -- cgit v1.2.1 From 7449c45d458dae3a121d0c4511cef844dabb4177 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Wed, 4 Oct 2017 16:52:22 -0500 Subject: fix add_issues_modal_spec --- spec/features/boards/add_issues_modal_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index c480b5b7e34..862d97a508f 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -101,8 +101,8 @@ describe 'Issue Boards add issue modal', :js do click_button 'Cancel' end - first('.board-delete').click - + accept_confirm { first('.board-delete').click } + click_button('Add issues') wait_for_requests -- cgit v1.2.1 From 035bf5d4d5d3209286aa257cbd56ec6ce9e1afb9 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Thu, 5 Oct 2017 16:13:21 -0500 Subject: fix create_snipper and diff_notes specs --- spec/features/merge_requests/user_posts_diff_notes_spec.rb | 6 +++--- spec/features/projects/snippets/create_snippet_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index 3b873d6f53c..8179100ef0d 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -76,7 +76,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'with an unfolded line' do before do - find('.js-unfold', match: :first).click + find('.js-unfold', match: :first).send_keys(:return) wait_for_requests end @@ -103,7 +103,7 @@ feature 'Merge requests > User posts diff notes', :js do it 'allows commenting' do should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]')) - first('.js-note-delete', visible: false).trigger('click') + first('.js-note-delete', visible: false).click should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]')) end @@ -135,7 +135,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'with an unfolded line' do before do - find('.js-unfold', match: :first).click + find('.js-unfold', match: :first).send_keys(:return) wait_for_requests end diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index 7dc779fa573..e4215291f99 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -10,7 +10,7 @@ feature 'Create Snippet', :js do fill_in 'project_snippet_title', with: 'My Snippet Title' fill_in 'project_snippet_description', with: 'My Snippet **Description**' page.within('.file-editor') do - find('.ace_text-input').native.send_keys('Hello World!') + find('.ace_text-input', visible: false).send_keys('Hello World!') end end @@ -59,7 +59,7 @@ feature 'Create Snippet', :js do fill_form dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif') - click_button('Create snippet') + find("input[value='Create snippet']").send_keys(:return) wait_for_requests expect(page).to have_content('My Snippet Title') -- cgit v1.2.1 From e0a68d458befab46f07eb7ab9a2f2a675f64e121 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 9 Oct 2017 15:17:24 -0500 Subject: Fixed click events --- spec/features/container_registry_spec.rb | 2 +- spec/support/helpers/merge_request_diff_helpers.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb index d5e9de20e59..bef2aa9e0e5 100644 --- a/spec/features/container_registry_spec.rb +++ b/spec/features/container_registry_spec.rb @@ -47,7 +47,7 @@ describe "Container Registry", :js do scenario 'user removes a specific tag from container repository' do visit_container_registry - find('.js-toggle-repo').trigger('click') + find('.js-toggle-repo').click wait_for_requests expect_any_instance_of(ContainerRegistry::Tag) diff --git a/spec/support/helpers/merge_request_diff_helpers.rb b/spec/support/helpers/merge_request_diff_helpers.rb index fd22e384b1b..c98aa503ed1 100644 --- a/spec/support/helpers/merge_request_diff_helpers.rb +++ b/spec/support/helpers/merge_request_diff_helpers.rb @@ -2,7 +2,7 @@ module MergeRequestDiffHelpers def click_diff_line(line_holder, diff_side = nil) line = get_line_components(line_holder, diff_side) line[:content].hover - line[:num].find('.add-diff-note').trigger('click') + line[:num].find('.add-diff-note', visible: false).send_keys(:return) end def get_line_components(line_holder, diff_side = nil) -- cgit v1.2.1 From 7e7baf7aab59f65dade40b6ad3c99231c1b1a4d9 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 9 Oct 2017 15:57:18 -0500 Subject: fix diff_notes_avatars_spec.rb failures in headless Chrome --- spec/features/merge_requests/diff_notes_avatars_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 2fcf7383471..e28eb463199 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -108,7 +108,7 @@ feature 'Diff note avatars', :js do expect(page).to have_selector('.notes_holder', visible: false) page.within find_line(position.line_code(project.repository)) do - first('img.js-diff-comment-avatar').send_keys(:return) + first('img.js-diff-comment-avatar').click end expect(page).to have_selector('.notes_holder') -- cgit v1.2.1 From 98b1b3fb87eb3f0f8bd16667266b591e79933ac2 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 9 Oct 2017 17:07:56 -0500 Subject: ensure javascript confirm dialog is accepted when attempting to delete boards --- spec/features/boards/boards_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 1311347a530..9c6c5d3739c 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -136,7 +136,7 @@ describe 'Issue Boards', :js do it 'allows user to delete board' do page.within(find('.board:nth-child(2)')) do - find('.board-delete').click + accept_confirm { find('.board-delete').click } end wait_for_requests @@ -151,7 +151,7 @@ describe 'Issue Boards', :js do find('.dropdown-menu-close').click page.within(find('.board:nth-child(2)')) do - find('.board-delete').click + accept_confirm { find('.board-delete').click } end wait_for_requests -- cgit v1.2.1 From 301204c2a3e663d87809ba2595e7388b5d3463ff Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 9 Oct 2017 17:08:46 -0500 Subject: resize window when simulating dragging as horizontal scrolling causes issues in tests --- spec/features/boards/boards_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 9c6c5d3739c..83ea9ee3b8b 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -560,6 +560,9 @@ describe 'Issue Boards', :js do end def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0) + # ensure there is enough horizontal space for four boards + page.current_window.resize_to(2000, 800) + drag_to(selector: selector, scrollable: '#board-app', list_from_index: list_from_index, -- cgit v1.2.1 From 73bb0029a3e4df66d74948cc0fc3ff693d8385fe Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 9 Oct 2017 17:19:43 -0500 Subject: chrome cannot send_keys unless the element is focusable --- spec/features/boards/boards_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 83ea9ee3b8b..08581bf19ba 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -518,7 +518,7 @@ describe 'Issue Boards', :js do end it 'allows user to use keyboard shortcuts' do - find('.boards-list').native.send_keys('i') + find('body').native.send_keys('i') expect(page).to have_content('New Issue') end end -- cgit v1.2.1 From 56025c7e6bbc4f7a084d9b384874ff322b3732fe Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 9 Oct 2017 23:13:57 -0500 Subject: accept javascript confirm when testing pipeline deletion --- spec/features/projects/pipeline_schedules_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 24b335a7068..fa2f7a1fd78 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -54,7 +54,7 @@ feature 'Pipeline Schedules', :js do end it 'deletes the pipeline' do - click_link 'Delete' + accept_confirm { click_link 'Delete' } expect(page).not_to have_css(".pipeline-schedule-table-row") end -- cgit v1.2.1 From 31c8fb987d656fed83b617092e79a42d9dd02590 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 10 Oct 2017 00:27:21 -0500 Subject: fix race condition when visiting file blob of recently triggered file upload --- spec/features/projects/user_browses_files_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/user_browses_files_spec.rb index f43b11c9485..1d7c8a731f0 100644 --- a/spec/features/projects/user_browses_files_spec.rb +++ b/spec/features/projects/user_browses_files_spec.rb @@ -175,10 +175,11 @@ describe 'User browses files' do page.within('#modal-upload-blob') do fill_in(:commit_message, with: 'New commit message') + fill_in(:branch_name, with: 'new_branch_name', visible: true) + click_button('Upload file') end - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Upload file') + block_and_wait_for_requests_complete visit(project_blob_path(project, 'new_branch_name/logo_sample.svg')) -- cgit v1.2.1 From 9aed01f0e9422eeb010f991f75f53849be500e6e Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 10 Oct 2017 14:20:51 -0500 Subject: accept confirm dialog when cancelling a pipeline --- spec/features/projects/pipelines/pipelines_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index ddf4678de9d..be8ff727a43 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -232,7 +232,7 @@ describe 'Pipelines', :js do context 'when canceling' do before do - find('.js-pipelines-cancel-button').click + accept_alert { find('.js-pipelines-cancel-button').click } end it 'indicates that pipeline was canceled' do -- cgit v1.2.1 From 85b915c39b8327afdfec5444c732f1b119081e0e Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 10 Oct 2017 15:43:05 -0500 Subject: fix click trigger method --- spec/support/features/discussion_comments_shared_example.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb index e3988b24469..b65b1300769 100644 --- a/spec/support/features/discussion_comments_shared_example.rb +++ b/spec/support/features/discussion_comments_shared_example.rb @@ -71,7 +71,7 @@ shared_examples 'discussion comments' do |resource_name| expect(page).not_to have_selector menu_selector find(toggle_selector).click - find('body').trigger 'click' + find('body').click expect(page).not_to have_selector menu_selector end -- cgit v1.2.1 From e118e3cdaadf6fd776462da84676cbacca643fa0 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 10 Oct 2017 15:56:27 -0500 Subject: fixed shared discussion_comments example --- .../features/discussion_comments_shared_example.rb | 32 ++++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb index b65b1300769..a2c8c9fb851 100644 --- a/spec/support/features/discussion_comments_shared_example.rb +++ b/spec/support/features/discussion_comments_shared_example.rb @@ -4,6 +4,7 @@ shared_examples 'discussion comments' do |resource_name| let(:toggle_selector) { "#{dropdown_selector} .dropdown-toggle" } let(:menu_selector) { "#{dropdown_selector} .dropdown-menu" } let(:submit_selector) { "#{form_selector} .js-comment-submit-button" } + let(:submit_button) { ".js-comment-submit-button" } let(:close_selector) { "#{form_selector} .btn-comment-and-close" } let(:comments_selector) { '.timeline > .note.timeline-entry' } @@ -85,17 +86,26 @@ shared_examples 'discussion comments' do |resource_name| find(toggle_selector).click find("#{menu_selector} .divider").click else - find(menu_selector).click + within dropdown_selector do + find('.dropdown-toggle').click - expect(page).to have_selector menu_selector - expect(find(dropdown_selector)).to have_content 'Comment' + expect(find('.dropdown-menu')).not_to be_nil + find('li[data-submit-text="Comment"]').click + expect(find(submit_button).value).to eq "Comment" - find("#{menu_selector} .divider").click + find('.dropdown-toggle').click + page.driver.execute_script( + "document.querySelector('.comment-type-dropdown .dropdown-menu .divider').click()" + ) - expect(page).to have_selector menu_selector + expect(find('.dropdown-menu')).not_to be_nil + find('li[data-submit-text="Comment"]').click + end end - expect(find(dropdown_selector)).to have_content 'Comment' + within dropdown_selector do + expect(find(submit_button).value).to eq "Comment" + end end describe 'when selecting "Start discussion"' do @@ -105,7 +115,9 @@ shared_examples 'discussion comments' do |resource_name| end it 'updates the submit button text and closes the dropdown' do - expect(find(dropdown_selector)).to have_content 'Start discussion' + within dropdown_selector do + expect(find(submit_button).value).to eq "Start discussion" + end expect(page).not_to have_selector menu_selector end @@ -170,7 +182,9 @@ shared_examples 'discussion comments' do |resource_name| end it 'updates the submit button text and closes the dropdown' do - expect(find(dropdown_selector)).to have_content 'Comment' + within dropdown_selector do + expect(find(submit_button).value).to eq "Comment" + end expect(page).not_to have_selector menu_selector end @@ -218,7 +232,7 @@ shared_examples 'discussion comments' do |resource_name| end it "should show a 'Start discussion & reopen #{resource_name}' button when 'Start discussion' is selected" do - find(toggle_selector).click + find(toggle_selector).send_keys(:return) find("#{menu_selector} li", match: :first) all("#{menu_selector} li").last.click -- cgit v1.2.1 From 59bb5bc54f6b5d502cd9761c230134e1ead73364 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Tue, 10 Oct 2017 15:56:43 -0500 Subject: Fix rubocop lints --- spec/features/boards/add_issues_modal_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index 862d97a508f..e4cfcea45a5 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -102,7 +102,7 @@ describe 'Issue Boards add issue modal', :js do end accept_confirm { first('.board-delete').click } - + click_button('Add issues') wait_for_requests -- cgit v1.2.1 From 3ac444b8da3a570cf79c3f9532e6e2d60b4033bd Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Wed, 11 Oct 2017 16:54:05 -0500 Subject: Fix trigger elements and element is not clickable at this position --- .../projects/merge_requests/user_comments_on_diff_spec.rb | 12 +++++++----- spec/features/protected_branches_spec.rb | 8 ++++---- .../features/protected_branches_access_control_ce.rb | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/spec/features/projects/merge_requests/user_comments_on_diff_spec.rb b/spec/features/projects/merge_requests/user_comments_on_diff_spec.rb index f34302f25f8..94cd167c36a 100644 --- a/spec/features/projects/merge_requests/user_comments_on_diff_spec.rb +++ b/spec/features/projects/merge_requests/user_comments_on_diff_spec.rb @@ -31,7 +31,7 @@ describe 'User comments on a diff', :js do page.within('.files > div:nth-child(3)') do expect(page).to have_content('Line is wrong') - find('.js-toggle-diff-comments').trigger('click') + find('.js-toggle-diff-comments').click expect(page).not_to have_content('Line is wrong') end @@ -64,7 +64,7 @@ describe 'User comments on a diff', :js do # Hide the comment. page.within('.files > div:nth-child(3)') do - find('.js-toggle-diff-comments').trigger('click') + find('.js-toggle-diff-comments').click expect(page).not_to have_content('Line is wrong') end @@ -77,7 +77,7 @@ describe 'User comments on a diff', :js do # Show the comment. page.within('.files > div:nth-child(3)') do - find('.js-toggle-diff-comments').trigger('click') + find('.js-toggle-diff-comments').click end # Now both the comments should be shown. @@ -90,7 +90,9 @@ describe 'User comments on a diff', :js do end # Check the same comments in the side-by-side view. - click_link('Side-by-side') + page.execute_script( + "document.querySelector('#parallel-diff-btn').click()" + ) wait_for_requests @@ -157,7 +159,7 @@ describe 'User comments on a diff', :js do end page.within('.merge-request-tabs') do - find('.notes-tab').trigger('click') + find('.notes-tab').click end wait_for_requests diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 2ab1eda90f1..a4084818284 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -48,7 +48,7 @@ feature 'Protected Branches', :js do expect(page).to have_content('fix') expect(find('.all-branches')).to have_selector('li', count: 1) - page.find('[data-target="#modal-delete-branch"]').trigger(:click) + page.find('[data-target="#modal-delete-branch"]').click expect(page).to have_css('.js-delete-branch[disabled]') fill_in 'delete_branch_input', with: 'fix' @@ -67,9 +67,9 @@ feature 'Protected Branches', :js do form = '.js-new-protected-branch' within form do - find(".js-allowed-to-merge").trigger('click') + find(".js-allowed-to-merge").click click_link 'No one' - find(".js-allowed-to-push").trigger('click') + find(".js-allowed-to-push").click click_link 'Developers + Masters' end @@ -171,7 +171,7 @@ feature 'Protected Branches', :js do end def set_protected_branch_name(branch_name) - find(".js-protected-branch-select").trigger('click') + find(".js-protected-branch-select").click find(".dropdown-input-field").set(branch_name) click_on("Create wildcard #{branch_name}") end diff --git a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb index 72bb0f2e9b9..5fde91512da 100644 --- a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb +++ b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb @@ -34,7 +34,7 @@ shared_examples "protected branches > access control > CE" do within('.js-allowed-to-push-container') do expect(first("li")).to have_content("Roles") - click_on access_type_name + find(:link, access_type_name).click end end @@ -79,7 +79,7 @@ shared_examples "protected branches > access control > CE" do within('.js-allowed-to-merge-container') do expect(first("li")).to have_content("Roles") - click_on access_type_name + find(:link, access_type_name).click end end -- cgit v1.2.1 From b0c2772a900bd4390d0ead7192e1bda3acd01bab Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 12 Oct 2017 11:31:29 -0500 Subject: convert Autosave into pure es module and remove global export --- app/assets/javascripts/autosave.js | 31 +++++++++------------- app/assets/javascripts/issuable_form.js | 2 +- app/assets/javascripts/notes.js | 4 +-- .../notes/components/issue_comment_form.vue | 3 +-- app/assets/javascripts/notes/mixins/autosave.js | 3 +-- 5 files changed, 18 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/autosave.js b/app/assets/javascripts/autosave.js index 4d2d4db7c0e..73bdab4ecb7 100644 --- a/app/assets/javascripts/autosave.js +++ b/app/assets/javascripts/autosave.js @@ -1,8 +1,9 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-param-reassign, quotes, prefer-template, no-var, one-var, no-unused-vars, one-var-declaration-per-line, no-void, consistent-return, no-empty, max-len */ +/* eslint-disable no-param-reassign, prefer-template, no-var, no-void, consistent-return */ + import AccessorUtilities from './lib/utils/accessor'; -window.Autosave = (function() { - function Autosave(field, key, resource) { +export default class Autosave { + constructor(field, key, resource) { this.field = field; this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); this.resource = resource; @@ -12,14 +13,10 @@ window.Autosave = (function() { this.key = 'autosave/' + key; this.field.data('autosave', this); this.restore(); - this.field.on('input', (function(_this) { - return function() { - return _this.save(); - }; - })(this)); + this.field.on('input', () => this.save()); } - Autosave.prototype.restore = function() { + restore() { var text; if (!this.isLocalStorageAvailable) return; @@ -40,9 +37,9 @@ window.Autosave = (function() { field.dispatchEvent(event); } } - }; + } - Autosave.prototype.save = function() { + save() { var text; text = this.field.val(); @@ -51,15 +48,13 @@ window.Autosave = (function() { } return this.reset(); - }; + } - Autosave.prototype.reset = function() { + reset() { if (!this.isLocalStorageAvailable) return; return window.localStorage.removeItem(this.key); - }; - - return Autosave; -})(); + } +} -export default window.Autosave; +window.Autosave = Autosave; diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js index 470c39c6f76..10f853066ca 100644 --- a/app/assets/javascripts/issuable_form.js +++ b/app/assets/javascripts/issuable_form.js @@ -1,9 +1,9 @@ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, quotes, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */ /* global GitLab */ -/* global Autosave */ /* global dateFormat */ import Pikaday from 'pikaday'; +import Autosave from './autosave'; import UsersSelect from './users_select'; import GfmAutoComplete from './gfm_auto_complete'; import ZenMode from './zen_mode'; diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 790f78d2e11..a09f938a281 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -5,7 +5,7 @@ default-case, prefer-template, consistent-return, no-alert, no-return-assign, no-param-reassign, prefer-arrow-callback, no-else-return, comma-dangle, no-new, brace-style, no-lonely-if, vars-on-top, no-unused-vars, no-sequences, no-shadow, newline-per-chained-call, no-useless-escape, class-methods-use-this */ -/* global Autosave */ + /* global ResolveService */ /* global mrRefreshWidgetUrl */ @@ -21,7 +21,7 @@ import Flash from './flash'; import CommentTypeToggle from './comment_type_toggle'; import GLForm from './gl_form'; import loadAwardsHandler from './awards_handler'; -import './autosave'; +import Autosave from './autosave'; import './dropzone_input'; import TaskList from './task_list'; import { ajaxPost, isInViewport, getPagePath, scrollToElement, isMetaKey } from './lib/utils/common_utils'; diff --git a/app/assets/javascripts/notes/components/issue_comment_form.vue b/app/assets/javascripts/notes/components/issue_comment_form.vue index 2ce52e4538a..ad384a1cc36 100644 --- a/app/assets/javascripts/notes/components/issue_comment_form.vue +++ b/app/assets/javascripts/notes/components/issue_comment_form.vue @@ -1,10 +1,9 @@ @@ -73,8 +91,13 @@ export default { :img-alt="imgAlt" :css-classes="imgCssClasses" :size="imgSize" - :tooltip-text="tooltipText" + :tooltip-text="avatarTooltipText" + :tooltip-placement="tooltipPlacement" + /> + >{{username}} diff --git a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js index 52e450e9ba5..ce75df6fc7b 100644 --- a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js @@ -11,6 +11,7 @@ describe('User Avatar Link Component', function () { imgCssClasses: 'myextraavatarclass', tooltipText: 'tooltip text', tooltipPlacement: 'bottom', + username: 'username', }; const UserAvatarLinkComponent = Vue.extend(UserAvatarLink); @@ -47,4 +48,42 @@ describe('User Avatar Link Component', function () { expect(this.userAvatarLink[key]).toBeDefined(); }); }); + + describe('no username', function () { + beforeEach(function (done) { + this.userAvatarLink.username = ''; + + Vue.nextTick(done); + }); + + it('should not render as a child element', function () { + expect(this.userAvatarLink.$el.querySelector('span')).toBeNull(); + }); + + it('should render avatar image tooltip', function () { + expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual(this.propsData.tooltipText); + }); + }); + + describe('username', function () { + it('should not render avatar image tooltip', function () { + expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual(''); + }); + + it('should render as a child element', function () { + expect(this.userAvatarLink.$el.querySelector('span')).toBeDefined(); + }); + + it('should render username prop in ', function () { + expect(this.userAvatarLink.$el.querySelector('span').innerText.trim()).toEqual(this.propsData.username); + }); + + it('should render text tooltip for ', function () { + expect(this.userAvatarLink.$el.querySelector('span').dataset.originalTitle).toEqual(this.propsData.tooltipText); + }); + + it('should render text tooltip placement for ', function () { + expect(this.userAvatarLink.$el.querySelector('span').getAttribute('tooltip-placement')).toEqual(this.propsData.tooltipPlacement); + }); + }); }); -- cgit v1.2.1 From b673fcc14fceb7553a3e2ddf375ad45b93106ea9 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Thu, 19 Oct 2017 16:59:49 +0200 Subject: clear localstorage between tests --- spec/features/issues/markdown_toolbar_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb index 6869c2c869d..c50a676d959 100644 --- a/spec/features/issues/markdown_toolbar_spec.rb +++ b/spec/features/issues/markdown_toolbar_spec.rb @@ -11,6 +11,10 @@ feature 'Issue markdown toolbar', :js do visit project_issue_path(project, issue) end + after do + execute_script("localStorage.clear();"); + end + it "doesn't include first new line when adding bold" do find('#note-body').native.send_keys('test') find('#note-body').native.send_key(:enter) -- cgit v1.2.1 From 95d629a1ea20f84e9286fbe5ae73ed3302a67c1c Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Fri, 20 Oct 2017 08:28:38 +0300 Subject: fix rubocop (oops) --- spec/features/issues/gfm_autocomplete_spec.rb | 8 ++++---- spec/features/issues/markdown_toolbar_spec.rb | 2 +- spec/support/input_helper.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 640e29183be..31291aed349 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -17,13 +17,13 @@ feature 'GFM autocomplete', :js do end after do - execute_script("localStorage.clear();"); + execute_script("localStorage.clear();") end it 'updates issue descripton with GFM reference' do find('.issuable-edit').click - simulateInput('#issue-description', "@#{user.name[0...3]}") + simulate_input('#issue-description', "@#{user.name[0...3]}") find('.atwho-view .cur').click @@ -106,7 +106,7 @@ feature 'GFM autocomplete', :js do it 'includes items for assignee dropdowns with non-ASCII characters in name' do page.within '.timeline-content-form' do find('#note-body').native.send_keys('') - simulateInput('#note-body', "@#{user.name[0...8]}"); + simulate_input('#note-body', "@#{user.name[0...8]}") end expect(page).to have_selector('.atwho-container') @@ -134,7 +134,7 @@ feature 'GFM autocomplete', :js do note = find('#note-body') page.within '.timeline-content-form' do note.native.send_keys('') - simulateInput('#note-body', "~#{label.title[0]}") + simulate_input('#note-body', "~#{label.title[0]}") note.click end diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb index c50a676d959..ee68dfc7a04 100644 --- a/spec/features/issues/markdown_toolbar_spec.rb +++ b/spec/features/issues/markdown_toolbar_spec.rb @@ -12,7 +12,7 @@ feature 'Issue markdown toolbar', :js do end after do - execute_script("localStorage.clear();"); + execute_script("localStorage.clear();") end it "doesn't include first new line when adding bold" do diff --git a/spec/support/input_helper.rb b/spec/support/input_helper.rb index d51c4fa3970..7a538272e3e 100644 --- a/spec/support/input_helper.rb +++ b/spec/support/input_helper.rb @@ -1,7 +1,7 @@ # see app/assets/javascripts/test_utils/simulate_input.js module InputHelper - def simulateInput(selector, input = '') + def simulate_input(selector, input = '') evaluate_script("window.simulateInput(#{selector.to_json}, #{input.to_json});") end end -- cgit v1.2.1 From ce7449ce032039467c7b6b1271b4b00a642a1c81 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Fri, 20 Oct 2017 09:05:18 +0300 Subject: clear localStorage after each capybara test (global) --- spec/features/issues/gfm_autocomplete_spec.rb | 4 ---- spec/features/issues/markdown_toolbar_spec.rb | 4 ---- spec/support/capybara.rb | 3 +++ 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 31291aed349..ac75b1fcdba 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -16,10 +16,6 @@ feature 'GFM autocomplete', :js do wait_for_requests end - after do - execute_script("localStorage.clear();") - end - it 'updates issue descripton with GFM reference' do find('.issuable-edit').click diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb index ee68dfc7a04..6869c2c869d 100644 --- a/spec/features/issues/markdown_toolbar_spec.rb +++ b/spec/features/issues/markdown_toolbar_spec.rb @@ -11,10 +11,6 @@ feature 'Issue markdown toolbar', :js do visit project_issue_path(project, issue) end - after do - execute_script("localStorage.clear();") - end - it "doesn't include first new line when adding bold" do find('#note-body').native.send_keys('test') find('#note-body').native.send_key(:enter) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index b5b98f19694..3755648aaf7 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -45,6 +45,9 @@ RSpec.configure do |config| end config.after(:example, :js) do |example| + # prevent localstorage from introducing side effects based on test order + execute_script("localStorage.clear();") + # capybara/rspec already calls Capybara.reset_sessions! in an `after` hook, # but `block_and_wait_for_requests_complete` is called before it so by # calling it explicitely here, we prevent any new requests from being fired -- cgit v1.2.1 From c44dff9984d4ee055a40b9c3354888193b3d5f57 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 20 Oct 2017 13:28:30 +0100 Subject: Remove page-specific GLForm init and add support_autocomplete: false local to groups/milestones/_form --- app/assets/javascripts/dispatcher.js | 1 - app/views/groups/milestones/_form.html.haml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 2885923aeda..eb576672d25 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -234,7 +234,6 @@ import DueDateSelectors from './due_date_select'; case 'groups:milestones:update': new ZenMode(); new DueDateSelectors(); - new GLForm($('.milestone-form'), true); break; case 'projects:compare:show': new gl.Diff(); diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml index cc879e5a308..a1be0d3220a 100644 --- a/app/views/groups/milestones/_form.html.haml +++ b/app/views/groups/milestones/_form.html.haml @@ -11,7 +11,7 @@ = f.label :description, "Description", class: "control-label" .col-sm-10 = render layout: 'projects/md_preview', locals: { url: group_preview_markdown_path } do - = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...' + = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false .clearfix .error-alert -- cgit v1.2.1 From c8d29d17aef6ac4fd0620dc0d69df5ef454fd102 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Fri, 20 Oct 2017 17:11:31 +0100 Subject: Added group milestones form spec --- spec/features/groups/milestone_spec.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb index 12aa54a3da1..1b41b3842c8 100644 --- a/spec/features/groups/milestone_spec.rb +++ b/spec/features/groups/milestone_spec.rb @@ -19,9 +19,9 @@ feature 'Group milestones', :js do end it 'renders description preview' do - form = find('.gfm-form') + description = find('.note-textarea') - form.fill_in(:milestone_description, with: '') + description.native.send_keys('') click_link('Preview') @@ -31,7 +31,7 @@ feature 'Group milestones', :js do click_link('Write') - form.fill_in(:milestone_description, with: ':+1: Nice') + description.native.send_keys(':+1: Nice') click_link('Preview') @@ -51,6 +51,13 @@ feature 'Group milestones', :js do expect(find('.start_date')).to have_content(Date.today.at_beginning_of_month.strftime('%b %-d, %Y')) end + + it 'description input does not support autocomplete' do + description = find('.note-textarea') + description.native.send_keys('!') + + expect(page).not_to have_selector('.atwho-view') + end end context 'milestones list' do -- cgit v1.2.1 From 3176eb83b6da5a66d6a506c7967f434732ae6864 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Sat, 21 Oct 2017 16:19:04 +0100 Subject: Added discussion_line_code value to note response and use it to query the right row for the discussion UI --- app/assets/javascripts/notes.js | 3 ++- app/controllers/concerns/notes_actions.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 9c008da1a5d..cf247a4c170 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -414,7 +414,8 @@ export default class Notes { } this.note_ids.push(noteEntity.id); form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); - row = form.closest('tr'); + + row = form.length ? form.closest('tr') : $(`#${noteEntity.discussion_line_code}`); if (noteEntity.on_image) { row = form; diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index 1126f706393..688bf16cfea 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -106,7 +106,8 @@ module NotesActions discussion_resolvable: discussion.resolvable?, diff_discussion_html: diff_discussion_html(discussion), - discussion_html: discussion_html(discussion) + discussion_html: discussion_html(discussion), + discussion_line_code: discussion.line_code, ) end end -- cgit v1.2.1 From d635f8bbe17e05fb6b69ccd79b127660039c5894 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Sat, 21 Oct 2017 18:16:35 +0100 Subject: Improve discussion_line_code set and update notes_controller_spec --- app/controllers/concerns/notes_actions.rb | 3 ++- spec/controllers/projects/notes_controller_spec.rb | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index 688bf16cfea..d46a4dffa29 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -107,8 +107,9 @@ module NotesActions diff_discussion_html: diff_discussion_html(discussion), discussion_html: discussion_html(discussion), - discussion_line_code: discussion.line_code, ) + + attrs[:discussion_line_code] = discussion.line_code if discussion.is_a?(DiffDiscussion) end end else diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 135fd6449ff..0081dcf599c 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -59,6 +59,7 @@ describe Projects::NotesController do expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:diff_discussion_html]).to be_nil + expect(note_json[:discussion_line_code]).to be_nil end end @@ -74,6 +75,7 @@ describe Projects::NotesController do expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:diff_discussion_html]).not_to be_nil + expect(note_json[:discussion_line_code]).not_to be_nil end end @@ -92,6 +94,7 @@ describe Projects::NotesController do expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:diff_discussion_html]).to be_nil + expect(note_json[:discussion_line_code]).to be_nil end end @@ -104,6 +107,7 @@ describe Projects::NotesController do expect(note_json[:id]).to eq(note.id) expect(note_json[:discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil + expect(note_json[:discussion_line_code]).to be_nil end end end @@ -120,6 +124,7 @@ describe Projects::NotesController do expect(note_json[:html]).not_to be_nil expect(note_json[:discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil + expect(note_json[:discussion_line_code]).to be_nil end end -- cgit v1.2.1 From 8bb17358b535fd288edb46bee389acf481a5e2f9 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Sat, 21 Oct 2017 20:52:17 +0300 Subject: Update docs on creating MRs --- doc/gitlab-basics/add-merge-request.md | 23 +++++++++------------ doc/gitlab-basics/img/merge_request_new.png | Bin 2234 -> 0 bytes .../img/merge_request_select_branch.png | Bin 20332 -> 16668 bytes doc/gitlab-basics/img/project_navbar.png | Bin 3259 -> 0 bytes 4 files changed, 10 insertions(+), 13 deletions(-) delete mode 100644 doc/gitlab-basics/img/merge_request_new.png delete mode 100644 doc/gitlab-basics/img/project_navbar.png diff --git a/doc/gitlab-basics/add-merge-request.md b/doc/gitlab-basics/add-merge-request.md index bf01fe51dc3..5cc014419ad 100644 --- a/doc/gitlab-basics/add-merge-request.md +++ b/doc/gitlab-basics/add-merge-request.md @@ -3,31 +3,28 @@ Merge requests are useful to integrate separate changes that you've made to a project, on different branches. This is a brief guide on how to create a merge request. For more information, check the -[merge requests documentation](../user/project/merge_requests.md). +[merge requests documentation](../user/project/merge_requests/index.md). --- 1. Before you start, you should have already [created a branch](create-branch.md) and [pushed your changes](basic-git-commands.md) to GitLab. - -1. You can then go to the project where you'd like to merge your changes and - click on the **Merge requests** tab. - - ![Merge requests](img/project_navbar.png) - +1. Go to the project where you'd like to merge your changes and click on the + **Merge requests** tab. 1. Click on **New merge request** on the right side of the screen. - - ![New Merge Request](img/merge_request_new.png) - -1. Select a source branch and click on the **Compare branches and continue** button. +1. From there on, you have the option to select the source branch and the target + branch you'd like to compare to. The default target project is the upstream + repository, but you can choose to compare across any of its forks. ![Select a branch](img/merge_request_select_branch.png) +1. When ready, click on the **Compare branches and continue** button. 1. At a minimum, add a title and a description to your merge request. Optionally, select a user to review your merge request and to accept or close it. You may also select a milestone and labels. ![New merge request page](img/merge_request_page.png) -1. When ready, click on the **Submit merge request** button. Your merge request - will be ready to be approved and published. +1. When ready, click on the **Submit merge request** button. + +Your merge request will be ready to be approved and merged. diff --git a/doc/gitlab-basics/img/merge_request_new.png b/doc/gitlab-basics/img/merge_request_new.png deleted file mode 100644 index 6fcd7bebada..00000000000 Binary files a/doc/gitlab-basics/img/merge_request_new.png and /dev/null differ diff --git a/doc/gitlab-basics/img/merge_request_select_branch.png b/doc/gitlab-basics/img/merge_request_select_branch.png index 9f6b93943a9..57ea0e65f34 100644 Binary files a/doc/gitlab-basics/img/merge_request_select_branch.png and b/doc/gitlab-basics/img/merge_request_select_branch.png differ diff --git a/doc/gitlab-basics/img/project_navbar.png b/doc/gitlab-basics/img/project_navbar.png deleted file mode 100644 index be6f38ede32..00000000000 Binary files a/doc/gitlab-basics/img/project_navbar.png and /dev/null differ -- cgit v1.2.1 From 126c4d995202b754634430cdaaea784f9c6dff4a Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Sat, 21 Oct 2017 21:05:32 +0300 Subject: Fix wording on CI disposable variables --- doc/ci/variables/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index 73568757aaa..bdd416b8372 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -43,7 +43,7 @@ future GitLab releases.** | **CI_COMMIT_TAG** | 9.0 | 0.5 | The commit tag name. Present only when building tags. | | **CI_CONFIG_PATH** | 9.4 | 0.5 | The path to CI config file. Defaults to `.gitlab-ci.yml` | | **CI_DEBUG_TRACE** | all | 1.7 | Whether [debug tracing](#debug-tracing) is enabled | -| **CI_DISPOSABLE_ENVIRONMENT** | all | 10.1 | Mark that job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except `shell` and `ssh`). If the environment is disposable, it is set to true, otherwise it is not defined at all. | +| **CI_DISPOSABLE_ENVIRONMENT** | all | 10.1 | Marks that the job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except `shell` and `ssh`). If the environment is disposable, it is set to true, otherwise it is not defined at all. | | **CI_ENVIRONMENT_NAME** | 8.15 | all | The name of the environment for this job | | **CI_ENVIRONMENT_SLUG** | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. | | **CI_ENVIRONMENT_URL** | 9.3 | all | The URL of the environment for this job | @@ -74,7 +74,7 @@ future GitLab releases.** | **CI_SERVER_NAME** | all | all | The name of CI server that is used to coordinate jobs | | **CI_SERVER_REVISION** | all | all | GitLab revision that is used to schedule jobs | | **CI_SERVER_VERSION** | all | all | GitLab version that is used to schedule jobs | -| **CI_SHARED_ENVIRONMENT** | all | 10.1 | Mark that job is executed in a shared environment (something that is persisted across CI invocations like `shell` or `ssh` executor). If the environment is shared, it is set to true, otherwise it is not defined at all. | +| **CI_SHARED_ENVIRONMENT** | all | 10.1 | Marks that the job is executed in a shared environment (something that is persisted across CI invocations like `shell` or `ssh` executor). If the environment is shared, it is set to true, otherwise it is not defined at all. | | **ARTIFACT_DOWNLOAD_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to download artifacts running a job | | **GET_SOURCES_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to fetch sources running a job | | **GITLAB_CI** | all | all | Mark that job is executed in GitLab CI environment | -- cgit v1.2.1 From 09e6b8b9615d888cbd8f585cfef05b18ca6639ec Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Sat, 21 Oct 2017 19:23:00 +0100 Subject: Remove trailing comma --- app/controllers/concerns/notes_actions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/concerns/notes_actions.rb b/app/controllers/concerns/notes_actions.rb index d46a4dffa29..3aa608c4792 100644 --- a/app/controllers/concerns/notes_actions.rb +++ b/app/controllers/concerns/notes_actions.rb @@ -106,7 +106,7 @@ module NotesActions discussion_resolvable: discussion.resolvable?, diff_discussion_html: diff_discussion_html(discussion), - discussion_html: discussion_html(discussion), + discussion_html: discussion_html(discussion) ) attrs[:discussion_line_code] = discussion.line_code if discussion.is_a?(DiffDiscussion) -- cgit v1.2.1 From 4082419442bfd7976034815508b4b1a18c52b389 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Sat, 21 Oct 2017 23:20:46 +0300 Subject: fix trailing whitespace --- spec/support/input_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/support/input_helper.rb b/spec/support/input_helper.rb index 7a538272e3e..acbb42274ec 100644 --- a/spec/support/input_helper.rb +++ b/spec/support/input_helper.rb @@ -5,4 +5,3 @@ module InputHelper evaluate_script("window.simulateInput(#{selector.to_json}, #{input.to_json});") end end - \ No newline at end of file -- cgit v1.2.1 From 285de09f36d1c33d7e052a7bd7ade2706d67fc68 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Sat, 21 Oct 2017 23:21:13 +0300 Subject: add CHROME_HEADLESS environment variable to disable headless mode --- spec/support/capybara.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 3755648aaf7..71c86fac3f4 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -9,9 +9,12 @@ timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 Capybara.javascript_driver = :chrome Capybara.register_driver :chrome do |app| + extra_args = [] + extra_args << 'headless' unless ENV['CHROME_HEADLESS'] =~ /^(false|no|0)$/i + capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( chromeOptions: { - 'args' => %w[headless no-sandbox disable-gpu --window-size=1240,1400] + 'args' => %w[no-sandbox disable-gpu --window-size=1240,1400] + extra_args } ) -- cgit v1.2.1 From e1d12ba9b988e61afb9317f3a132d6e2caa93923 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 13 Oct 2017 19:21:23 +0200 Subject: Refactor Clusters to be consisted from GcpProvider and KubernetesPlatform --- app/controllers/projects/clusters_controller.rb | 28 ++-- app/models/clusters/cluster.rb | 56 +++++++ app/models/clusters/cluster_project.rb | 6 + app/models/clusters/platforms/kubernetes.rb | 172 +++++++++++++++++++++ app/models/clusters/providers/gcp.rb | 79 ++++++++++ app/models/gcp/cluster.rb | 116 -------------- app/models/project.rb | 4 +- app/services/ci/create_cluster_service.rb | 15 -- app/services/ci/fetch_gcp_operation_service.rb | 17 -- app/services/ci/fetch_kubernetes_token_service.rb | 72 --------- .../ci/finalize_cluster_creation_service.rb | 33 ---- app/services/ci/integrate_cluster_service.rb | 26 ---- app/services/ci/provision_cluster_service.rb | 36 ----- app/services/ci/update_cluster_service.rb | 22 --- app/services/clusters/create_service.rb | 14 ++ .../clusters/gcp/fetch_operation_service.rb | 16 ++ .../clusters/gcp/finalize_creation_service.rb | 66 ++++++++ app/services/clusters/gcp/provision_service.rb | 49 ++++++ .../gcp/verify_provision_status_service.rb | 44 ++++++ app/services/clusters/update_service.rb | 7 + app/workers/cluster_provision_worker.rb | 6 +- app/workers/wait_for_cluster_creation_worker.rb | 21 +-- db/migrate/20171013094327_create_clusters.rb | 66 ++++++++ 23 files changed, 603 insertions(+), 368 deletions(-) create mode 100644 app/models/clusters/cluster.rb create mode 100644 app/models/clusters/cluster_project.rb create mode 100644 app/models/clusters/platforms/kubernetes.rb create mode 100644 app/models/clusters/providers/gcp.rb delete mode 100644 app/models/gcp/cluster.rb delete mode 100644 app/services/ci/create_cluster_service.rb delete mode 100644 app/services/ci/fetch_gcp_operation_service.rb delete mode 100644 app/services/ci/fetch_kubernetes_token_service.rb delete mode 100644 app/services/ci/finalize_cluster_creation_service.rb delete mode 100644 app/services/ci/integrate_cluster_service.rb delete mode 100644 app/services/ci/provision_cluster_service.rb delete mode 100644 app/services/ci/update_cluster_service.rb create mode 100644 app/services/clusters/create_service.rb create mode 100644 app/services/clusters/gcp/fetch_operation_service.rb create mode 100644 app/services/clusters/gcp/finalize_creation_service.rb create mode 100644 app/services/clusters/gcp/provision_service.rb create mode 100644 app/services/clusters/gcp/verify_provision_status_service.rb create mode 100644 app/services/clusters/update_service.rb create mode 100644 db/migrate/20171013094327_create_clusters.rb diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index 03019b0becc..0679d8c69f0 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -31,7 +31,7 @@ class Projects::ClustersController < Projects::ApplicationController end def create - @cluster = Ci::CreateClusterService + @cluster = Ci::CreateService .new(project, current_user, create_params) .execute(token_in_session) @@ -88,19 +88,27 @@ class Projects::ClustersController < Projects::ApplicationController def create_params params.require(:cluster).permit( - :gcp_project_id, - :gcp_cluster_zone, - :gcp_cluster_name, - :gcp_cluster_size, - :gcp_machine_type, - :project_namespace, - :enabled) + :enabled, + :platform_type, + :provider_type, + kubernetes_platform: [ + :namespace + ], + gcp_provider: [ + :project_id, + :cluster_zone, + :cluster_name, + :cluster_size, + :machine_type + ]) end def update_params params.require(:cluster).permit( - :project_namespace, - :enabled) + :enabled, + kubernetes_platform: [ + :namespace + ]) end def authorize_google_api diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb new file mode 100644 index 00000000000..d7b13ac88f2 --- /dev/null +++ b/app/models/clusters/cluster.rb @@ -0,0 +1,56 @@ +module Clusters + class Cluster < ActiveRecord::Base + include Presentable + + belongs_to :user + belongs_to :service + + enum :platform_type { + kubernetes: 1 + } + + enum :provider_type { + user: 0, + gcp: 1 + } + + has_many :cluster_projects + has_many :projects, through: :cluster_projects + + has_one :gcp_provider + has_one :kubernetes_platform + + accepts_nested_attributes_for :gcp_provider + accepts_nested_attributes_for :kubernetes_platform + + validates :kubernetes_platform, presence: true, if: :kubernetes? + validates :gcp_provider, presence: true, if: :gcp? + validate :restrict_modification, on: :update + + delegate :status, to: :provider, allow_nil: true + delegate :status_reason, to: :provider, allow_nil: true + + def restrict_modification + if provider&.on_creation? + errors.add(:base, "cannot modify during creation") + return false + end + + true + end + + def provider + return gcp_provider if gcp? + end + + def platform + return kubernetes_platform if kubernetes? + end + + def first_project + return @first_project if defined?(@first_project) + + @first_project = projects.first + end + end +end diff --git a/app/models/clusters/cluster_project.rb b/app/models/clusters/cluster_project.rb new file mode 100644 index 00000000000..7b139c2bb08 --- /dev/null +++ b/app/models/clusters/cluster_project.rb @@ -0,0 +1,6 @@ +module Clusters + class ClusterProject < ActiveRecord::Base + belongs_to :cluster + belongs_to :project + end +end diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb new file mode 100644 index 00000000000..aed6f733487 --- /dev/null +++ b/app/models/clusters/platforms/kubernetes.rb @@ -0,0 +1,172 @@ +module Clusters + module Platforms + class Kubernetes < ActiveRecord::Base + include Gitlab::Kubernetes + include ReactiveCaching + + TEMPLATE_PLACEHOLDER = 'Kubernetes namespace'.freeze + + self.reactive_cache_key = ->(service) { [service.class.model_name.singular, service.project_id] } + + belongs_to :cluster + + attr_encrypted :password, + mode: :per_attribute_iv, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + attr_encrypted :token, + mode: :per_attribute_iv, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + validates :namespace, + allow_blank: true, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + validates :api_url, url: true, presence: true + validates :token, presence: true + + after_save :clear_reactive_cache! + + before_validation :enforce_namespace_to_lower_case + + def actual_namespace + if namespace.present? + namespace + else + default_namespace + end + end + + def predefined_variables + config = YAML.dump(kubeconfig) + + variables = [ + { key: 'KUBE_URL', value: api_url, public: true }, + { key: 'KUBE_TOKEN', value: token, public: false }, + { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true }, + { key: 'KUBECONFIG', value: config, public: false, file: true } + ] + + if ca_pem.present? + variables << { key: 'KUBE_CA_PEM', value: ca_pem, public: true } + variables << { key: 'KUBE_CA_PEM_FILE', value: ca_pem, public: true, file: true } + end + + variables + end + + # Constructs a list of terminals from the reactive cache + # + # Returns nil if the cache is empty, in which case you should try again a + # short time later + def terminals(environment) + with_reactive_cache do |data| + pods = filter_by_label(data[:pods], app: environment.slug) + terminals = pods.flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) } + terminals.each { |terminal| add_terminal_auth(terminal, terminal_auth) } + end + end + + # Caches resources in the namespace so other calls don't need to block on + # network access + def calculate_reactive_cache + return unless active? && project && !project.pending_delete? + + # We may want to cache extra things in the future + { pods: read_pods } + end + + def kubeconfig + to_kubeconfig( + url: api_url, + namespace: actual_namespace, + token: token, + ca_pem: ca_pem) + end + + def namespace_placeholder + default_namespace || TEMPLATE_PLACEHOLDER + end + + def default_namespace + "#{cluster.first_project.path}-#{cluster.first_project.id}" if cluster.first_project + end + + def read_secrets + kubeclient = build_kubeclient! + + kubeclient.get_secrets.as_json + rescue KubeException => err + raise err unless err.error_code == 404 + [] + end + + # Returns a hash of all pods in the namespace + def read_pods + kubeclient = build_kubeclient! + + kubeclient.get_pods(namespace: actual_namespace).as_json + rescue KubeException => err + raise err unless err.error_code == 404 + [] + end + + def kubeclient_ssl_options + opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER } + + if ca_pem.present? + opts[:cert_store] = OpenSSL::X509::Store.new + opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem)) + end + + opts + end + + private + + def build_kubeclient!(api_path: 'api', api_version: 'v1') + raise "Incomplete settings" unless api_url && actual_namespace && token + + ::Kubeclient::Client.new( + join_api_url(api_path), + api_version, + auth_options: kubeclient_auth_options, + ssl_options: kubeclient_ssl_options, + http_proxy_uri: ENV['http_proxy'] + ) + end + + def kubeclient_auth_options + return { username: username, password: password } if username + return { bearer_token: token } if token + end + + def join_api_url(api_path) + url = URI.parse(api_url) + prefix = url.path.sub(%r{/+\z}, '') + + url.path = [prefix, api_path].join("/") + + url.to_s + end + + def terminal_auth + { + token: token, + ca_pem: ca_pem, + max_session_time: current_application_settings.terminal_max_session_time + } + end + + def enforce_namespace_to_lower_case + self.namespace = self.namespace&.downcase + end + end + end +end diff --git a/app/models/clusters/providers/gcp.rb b/app/models/clusters/providers/gcp.rb new file mode 100644 index 00000000000..5d4618cfe87 --- /dev/null +++ b/app/models/clusters/providers/gcp.rb @@ -0,0 +1,79 @@ +module Clusters + module Providers + class Gcp < ActiveRecord::Base + belongs_to :cluster + + default_value_for :cluster_zone, 'us-central1-a' + default_value_for :cluster_size, 3 + default_value_for :machine_type, 'n1-standard-4' + + attr_encrypted :access_token, + mode: :per_attribute_iv, + key: Gitlab::Application.secrets.db_key_base, + algorithm: 'aes-256-cbc' + + validates :project_id, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + validates :cluster_name, + length: 1..63, + format: { + with: Gitlab::Regex.kubernetes_namespace_regex, + message: Gitlab::Regex.kubernetes_namespace_regex_message + } + + validates :cluster_zone, presence: true + + validates :cluster_size, + presence: true, + numericality: { + only_integer: true, + greater_than: 0 + } + + state_machine :status, initial: :scheduled do + state :scheduled, value: 1 + state :creating, value: 2 + state :created, value: 3 + state :errored, value: 4 + + event :make_creating do + transition any - [:creating] => :creating + end + + event :make_created do + transition any - [:created] => :created + end + + event :make_errored do + transition any - [:errored] => :errored + end + + before_transition any => [:errored, :created] do |provider| + provider.token = nil + provider.operation_id = nil + provider.save! + end + + before_transition any => [:errored] do |provider, transition| + status_reason = transition.args.first + provider.status_reason = status_reason if status_reason + end + end + + def on_creation? + scheduled? || creating? + end + + def api_client + return unless access_token + + @api_client ||= GoogleApi::CloudPlatform::Client.new(access_token, nil) + end + end + end +end diff --git a/app/models/gcp/cluster.rb b/app/models/gcp/cluster.rb deleted file mode 100644 index 162a690c0e3..00000000000 --- a/app/models/gcp/cluster.rb +++ /dev/null @@ -1,116 +0,0 @@ -module Gcp - class Cluster < ActiveRecord::Base - extend Gitlab::Gcp::Model - include Presentable - - belongs_to :project, inverse_of: :cluster - belongs_to :user - belongs_to :service - - scope :enabled, -> { where(enabled: true) } - scope :disabled, -> { where(enabled: false) } - - default_value_for :gcp_cluster_zone, 'us-central1-a' - default_value_for :gcp_cluster_size, 3 - default_value_for :gcp_machine_type, 'n1-standard-4' - - attr_encrypted :password, - mode: :per_attribute_iv, - key: Gitlab::Application.secrets.db_key_base, - algorithm: 'aes-256-cbc' - - attr_encrypted :kubernetes_token, - mode: :per_attribute_iv, - key: Gitlab::Application.secrets.db_key_base, - algorithm: 'aes-256-cbc' - - attr_encrypted :gcp_token, - mode: :per_attribute_iv, - key: Gitlab::Application.secrets.db_key_base, - algorithm: 'aes-256-cbc' - - validates :gcp_project_id, - length: 1..63, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - validates :gcp_cluster_name, - length: 1..63, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - validates :gcp_cluster_zone, presence: true - - validates :gcp_cluster_size, - presence: true, - numericality: { - only_integer: true, - greater_than: 0 - } - - validates :project_namespace, - allow_blank: true, - length: 1..63, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - # if we do not do status transition we prevent change - validate :restrict_modification, on: :update, unless: :status_changed? - - state_machine :status, initial: :scheduled do - state :scheduled, value: 1 - state :creating, value: 2 - state :created, value: 3 - state :errored, value: 4 - - event :make_creating do - transition any - [:creating] => :creating - end - - event :make_created do - transition any - [:created] => :created - end - - event :make_errored do - transition any - [:errored] => :errored - end - - before_transition any => [:errored, :created] do |cluster| - cluster.gcp_token = nil - cluster.gcp_operation_id = nil - end - - before_transition any => [:errored] do |cluster, transition| - status_reason = transition.args.first - cluster.status_reason = status_reason if status_reason - end - end - - def project_namespace_placeholder - "#{project.path}-#{project.id}" - end - - def on_creation? - scheduled? || creating? - end - - def api_url - 'https://' + endpoint if endpoint - end - - def restrict_modification - if on_creation? - errors.add(:base, "cannot modify during creation") - return false - end - - true - end - end -end diff --git a/app/models/project.rb b/app/models/project.rb index 4689b588906..bc263b63881 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -177,7 +177,9 @@ class Project < ActiveRecord::Base has_one :import_data, class_name: 'ProjectImportData', inverse_of: :project, autosave: true has_one :project_feature, inverse_of: :project has_one :statistics, class_name: 'ProjectStatistics' - has_one :cluster, class_name: 'Gcp::Cluster', inverse_of: :project + + has_many :cluster_projects, class_name: 'Clusters::ClusterProject' + has_one :cluster, through: :cluster_projects # Container repositories need to remove data from the container registry, # which is not managed by the DB. Hence we're still using dependent: :destroy diff --git a/app/services/ci/create_cluster_service.rb b/app/services/ci/create_cluster_service.rb deleted file mode 100644 index f7ee0e468e2..00000000000 --- a/app/services/ci/create_cluster_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Ci - class CreateClusterService < BaseService - def execute(access_token) - params['gcp_machine_type'] ||= GoogleApi::CloudPlatform::Client::DEFAULT_MACHINE_TYPE - - cluster_params = - params.merge(user: current_user, - gcp_token: access_token) - - project.create_cluster(cluster_params).tap do |cluster| - ClusterProvisionWorker.perform_async(cluster.id) if cluster.persisted? - end - end - end -end diff --git a/app/services/ci/fetch_gcp_operation_service.rb b/app/services/ci/fetch_gcp_operation_service.rb deleted file mode 100644 index 0b68e4d6ea9..00000000000 --- a/app/services/ci/fetch_gcp_operation_service.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Ci - class FetchGcpOperationService - def execute(cluster) - api_client = - GoogleApi::CloudPlatform::Client.new(cluster.gcp_token, nil) - - operation = api_client.projects_zones_operations( - cluster.gcp_project_id, - cluster.gcp_cluster_zone, - cluster.gcp_operation_id) - - yield(operation) if block_given? - rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") - end - end -end diff --git a/app/services/ci/fetch_kubernetes_token_service.rb b/app/services/ci/fetch_kubernetes_token_service.rb deleted file mode 100644 index 44da87cb00c..00000000000 --- a/app/services/ci/fetch_kubernetes_token_service.rb +++ /dev/null @@ -1,72 +0,0 @@ -## -# TODO: -# Almost components in this class were copied from app/models/project_services/kubernetes_service.rb -# We should dry up those classes not to repeat the same code. -# Maybe we should have a special facility (e.g. lib/kubernetes_api) to maintain all Kubernetes API caller. -module Ci - class FetchKubernetesTokenService - attr_reader :api_url, :ca_pem, :username, :password - - def initialize(api_url, ca_pem, username, password) - @api_url = api_url - @ca_pem = ca_pem - @username = username - @password = password - end - - def execute - read_secrets.each do |secret| - name = secret.dig('metadata', 'name') - if /default-token/ =~ name - token_base64 = secret.dig('data', 'token') - return Base64.decode64(token_base64) if token_base64 - end - end - - nil - end - - private - - def read_secrets - kubeclient = build_kubeclient! - - kubeclient.get_secrets.as_json - rescue KubeException => err - raise err unless err.error_code == 404 - [] - end - - def build_kubeclient!(api_path: 'api', api_version: 'v1') - raise "Incomplete settings" unless api_url && username && password - - ::Kubeclient::Client.new( - join_api_url(api_path), - api_version, - auth_options: { username: username, password: password }, - ssl_options: kubeclient_ssl_options, - http_proxy_uri: ENV['http_proxy'] - ) - end - - def join_api_url(api_path) - url = URI.parse(api_url) - prefix = url.path.sub(%r{/+\z}, '') - - url.path = [prefix, api_path].join("/") - - url.to_s - end - - def kubeclient_ssl_options - opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER } - - if ca_pem.present? - opts[:cert_store] = OpenSSL::X509::Store.new - opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem)) - end - - opts - end - end -end diff --git a/app/services/ci/finalize_cluster_creation_service.rb b/app/services/ci/finalize_cluster_creation_service.rb deleted file mode 100644 index 347875c5697..00000000000 --- a/app/services/ci/finalize_cluster_creation_service.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Ci - class FinalizeClusterCreationService - def execute(cluster) - api_client = - GoogleApi::CloudPlatform::Client.new(cluster.gcp_token, nil) - - begin - gke_cluster = api_client.projects_zones_clusters_get( - cluster.gcp_project_id, - cluster.gcp_cluster_zone, - cluster.gcp_cluster_name) - rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") - end - - endpoint = gke_cluster.endpoint - api_url = 'https://' + endpoint - ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) - username = gke_cluster.master_auth.username - password = gke_cluster.master_auth.password - - kubernetes_token = Ci::FetchKubernetesTokenService.new( - api_url, ca_cert, username, password).execute - - unless kubernetes_token - return cluster.make_errored!('Failed to get a default token of kubernetes') - end - - Ci::IntegrateClusterService.new.execute( - cluster, endpoint, ca_cert, kubernetes_token, username, password) - end - end -end diff --git a/app/services/ci/integrate_cluster_service.rb b/app/services/ci/integrate_cluster_service.rb deleted file mode 100644 index d123ce8d26b..00000000000 --- a/app/services/ci/integrate_cluster_service.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Ci - class IntegrateClusterService - def execute(cluster, endpoint, ca_cert, token, username, password) - Gcp::Cluster.transaction do - cluster.update!( - enabled: true, - endpoint: endpoint, - ca_cert: ca_cert, - kubernetes_token: token, - username: username, - password: password, - service: cluster.project.find_or_initialize_service('kubernetes'), - status_event: :make_created) - - cluster.service.update!( - active: true, - api_url: cluster.api_url, - ca_pem: ca_cert, - namespace: cluster.project_namespace, - token: token) - end - rescue ActiveRecord::RecordInvalid => e - cluster.make_errored!("Failed to integrate cluster into kubernetes_service: #{e.message}") - end - end -end diff --git a/app/services/ci/provision_cluster_service.rb b/app/services/ci/provision_cluster_service.rb deleted file mode 100644 index 52d80b01813..00000000000 --- a/app/services/ci/provision_cluster_service.rb +++ /dev/null @@ -1,36 +0,0 @@ -module Ci - class ProvisionClusterService - def execute(cluster) - api_client = - GoogleApi::CloudPlatform::Client.new(cluster.gcp_token, nil) - - begin - operation = api_client.projects_zones_clusters_create( - cluster.gcp_project_id, - cluster.gcp_cluster_zone, - cluster.gcp_cluster_name, - cluster.gcp_cluster_size, - machine_type: cluster.gcp_machine_type) - rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") - end - - unless operation.status == 'RUNNING' || operation.status == 'PENDING' - return cluster.make_errored!("Operation status is unexpected; #{operation.status_message}") - end - - cluster.gcp_operation_id = api_client.parse_operation_id(operation.self_link) - - unless cluster.gcp_operation_id - return cluster.make_errored!('Can not find operation_id from self_link') - end - - if cluster.make_creating - WaitForClusterCreationWorker.perform_in( - WaitForClusterCreationWorker::INITIAL_INTERVAL, cluster.id) - else - return cluster.make_errored!("Failed to update cluster record; #{cluster.errors}") - end - end - end -end diff --git a/app/services/ci/update_cluster_service.rb b/app/services/ci/update_cluster_service.rb deleted file mode 100644 index 70d88fca660..00000000000 --- a/app/services/ci/update_cluster_service.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Ci - class UpdateClusterService < BaseService - def execute(cluster) - Gcp::Cluster.transaction do - cluster.update!(params) - - if params['enabled'] == 'true' - cluster.service.update!( - active: true, - api_url: cluster.api_url, - ca_pem: cluster.ca_cert, - namespace: cluster.project_namespace, - token: cluster.kubernetes_token) - else - cluster.service.update!(active: false) - end - end - rescue ActiveRecord::RecordInvalid => e - cluster.errors.add(:base, e.message) - end - end -end diff --git a/app/services/clusters/create_service.rb b/app/services/clusters/create_service.rb new file mode 100644 index 00000000000..5429bc21256 --- /dev/null +++ b/app/services/clusters/create_service.rb @@ -0,0 +1,14 @@ +module Clusters + class CreateService < BaseService + def execute(access_token) + params['gcp_machine_type'] ||= GoogleApi::CloudPlatform::Client::DEFAULT_MACHINE_TYPE + + cluster_params = + params.merge(user: current_user) + + project.create_cluster(cluster_params).tap do |cluster| + ClusterProvisionWorker.perform_async(cluster.id) if cluster.persisted? + end + end + end +end diff --git a/app/services/clusters/gcp/fetch_operation_service.rb b/app/services/clusters/gcp/fetch_operation_service.rb new file mode 100644 index 00000000000..013225efac4 --- /dev/null +++ b/app/services/clusters/gcp/fetch_operation_service.rb @@ -0,0 +1,16 @@ +module Clusters + module Gcp + class FetchOperationService + def execute(provider) + operation = provider.api_client.projects_zones_operations( + provider.project_id, + provider.cluster_zone, + provider.operation_id) + + yield(operation) if block_given? + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + return provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") + end + end + end +end diff --git a/app/services/clusters/gcp/finalize_creation_service.rb b/app/services/clusters/gcp/finalize_creation_service.rb new file mode 100644 index 00000000000..b536285b368 --- /dev/null +++ b/app/services/clusters/gcp/finalize_creation_service.rb @@ -0,0 +1,66 @@ +module Clusters + module Gcp + class FinalizeCreationService + attr_reader :provider + + def execute(provider) + @provider = provider + + configure_provider + configure_kubernetes_platform + request_kuberenetes_platform_token + + ActiveRecord::Base.transaction do + kubernetes_platform.update! + provider.make_created! + end + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + return cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") + rescue ActiveRecord::RecordInvalid => e + cluster.make_errored!("Failed to configure GKE Cluster: #{e.message}") + end + + private + + def configure_provider + provider.endpoint = gke_cluster.endpoint + end + + def configure_kubernetes_platform + kubernetes_platform = cluster.kubernetes_platform + kubernetes_platform.api_url = 'https://' + endpoint + kubernetes_platform.ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) + kubernetes_platform.username = gke_cluster.master_auth.username + kubernetes_platform.password = gke_cluster.master_auth.password + end + + def request_kuberenetes_platform_token + kubernetes_platform.read_secrets.each do |secret| + name = secret.dig('metadata', 'name') + if /default-token/ =~ name + token_base64 = secret.dig('data', 'token') + if token_base64 + kubernetes_platform.token = Base64.decode64(token_base64) + break + end + end + end + end + + def gke_cluster + @gke_cluster ||= provider.api_client.projects_zones_clusters_get( + provider.gcp_project_id, + provider.gcp_cluster_zone, + provider.gcp_cluster_name) + end + + def cluster + provider.cluster + end + + def kubernetes_platform + cluster.kubernetes_platform + end + end + end +end diff --git a/app/services/clusters/gcp/provision_service.rb b/app/services/clusters/gcp/provision_service.rb new file mode 100644 index 00000000000..269705000ac --- /dev/null +++ b/app/services/clusters/gcp/provision_service.rb @@ -0,0 +1,49 @@ +module Clusters + module Gcp + class ProvisionService + attr_reader :provider + + def execute(provider) + @provider = provider + + unless operation.status == 'RUNNING' || operation.status == 'PENDING' + return provider.make_errored!("Operation status is unexpected; #{operation.status_message}") + end + + provider.operation_id = operation_id + + unless provider.operation_id + return provider.make_errored!('Can not find operation_id from self_link') + end + + if provider.make_creating + WaitForClusterCreationWorker.perform_in( + WaitForClusterCreationWorker::INITIAL_INTERVAL, provider.id) + else + return provider.make_errored!("Failed to update provider record; #{provider.errors}") + end + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + return provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") + end + + private + + def operation_id + api_client.parse_operation_id(operation.self_link) + end + + def operation + @operation ||= api_client.projects_zones_providers_create( + provider.project_id, + provider.provider_zone, + provider.provider_name, + provider.provider_size, + machine_type: provider.machine_type) + end + + def api_client + provider.api_client + end + end + end +end diff --git a/app/services/clusters/gcp/verify_provision_status_service.rb b/app/services/clusters/gcp/verify_provision_status_service.rb new file mode 100644 index 00000000000..466ea986516 --- /dev/null +++ b/app/services/clusters/gcp/verify_provision_status_service.rb @@ -0,0 +1,44 @@ +module Clusters + module Gcp + class VerifyProvisionStatusService + attr_reader :provider + + INITIAL_INTERVAL = 2.minutes + EAGER_INTERVAL = 10.seconds + TIMEOUT = 20.minutes + + def execute(provider) + @provider = provider + + request_operation do |operation| + case operation.status + when 'RUNNING' + continue_creation(operation) + when 'DONE' + finalize_creation + else + return provider.make_errored!("Unexpected operation status; #{operation.status} #{operation.status_message}") + end + end + end + + private + + def continue_creation(operation) + if TIMEOUT < Time.now.utc - operation.start_time.to_time.utc + return provider.make_errored!("Cluster creation time exceeds timeout; #{TIMEOUT}") + end + + WaitForClusterCreationWorker.perform_in(EAGER_INTERVAL, provider.cluster_id) + end + + def finalize_creation + Clusters::Gcp::FinalizeCreationService.new.execute(provider) + end + + def request_operation(&blk) + Clusters::FetchGcpOperationService.new.execute(provider, &blk) + end + end + end +end diff --git a/app/services/clusters/update_service.rb b/app/services/clusters/update_service.rb new file mode 100644 index 00000000000..989218e32a2 --- /dev/null +++ b/app/services/clusters/update_service.rb @@ -0,0 +1,7 @@ +module Clusters + class UpdateService < BaseService + def execute(cluster) + cluster.update(params) + end + end +end diff --git a/app/workers/cluster_provision_worker.rb b/app/workers/cluster_provision_worker.rb index 63300b58a25..79f0d73c396 100644 --- a/app/workers/cluster_provision_worker.rb +++ b/app/workers/cluster_provision_worker.rb @@ -3,8 +3,10 @@ class ClusterProvisionWorker include ClusterQueue def perform(cluster_id) - Gcp::Cluster.find_by_id(cluster_id).try do |cluster| - Ci::ProvisionClusterService.new.execute(cluster) + Clusters::Cluster.find_by_id(cluster_id).try do |cluster| + cluster.gcp_provider.try do |provider| + Clusters::Gcp::ProvisionService.new.execute(provider) + end end end end diff --git a/app/workers/wait_for_cluster_creation_worker.rb b/app/workers/wait_for_cluster_creation_worker.rb index 5aa3bbdaa9d..d8c42c6bd55 100644 --- a/app/workers/wait_for_cluster_creation_worker.rb +++ b/app/workers/wait_for_cluster_creation_worker.rb @@ -2,25 +2,10 @@ class WaitForClusterCreationWorker include Sidekiq::Worker include ClusterQueue - INITIAL_INTERVAL = 2.minutes - EAGER_INTERVAL = 10.seconds - TIMEOUT = 20.minutes - def perform(cluster_id) - Gcp::Cluster.find_by_id(cluster_id).try do |cluster| - Ci::FetchGcpOperationService.new.execute(cluster) do |operation| - case operation.status - when 'RUNNING' - if TIMEOUT < Time.now.utc - operation.start_time.to_time.utc - return cluster.make_errored!("Cluster creation time exceeds timeout; #{TIMEOUT}") - end - - WaitForClusterCreationWorker.perform_in(EAGER_INTERVAL, cluster.id) - when 'DONE' - Ci::FinalizeClusterCreationService.new.execute(cluster) - else - return cluster.make_errored!("Unexpected operation status; #{operation.status} #{operation.status_message}") - end + Clusters::Cluster.find_by_id(cluster_id).try do |cluster| + cluster.gcp_provider.try do |provider| + Clusters::Gcp::VerifyProvisionStatusService.new.execute(provider) end end end diff --git a/db/migrate/20171013094327_create_clusters.rb b/db/migrate/20171013094327_create_clusters.rb new file mode 100644 index 00000000000..ad30181f984 --- /dev/null +++ b/db/migrate/20171013094327_create_clusters.rb @@ -0,0 +1,66 @@ +class CreateGcpClusters < ActiveRecord::Migration + DOWNTIME = false + + def change + create_table :clusters do |t| + t.references :user, foreign_key: { on_delete: :nullify } + + t.boolean :enabled, default: true + + t.integer :provider_type, null: false + t.integer :platform_type, null: false + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_projects do |t| + t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_kubernetes_platforms do |t| + t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + + t.string :api_url + t.text :ca_cert + + t.string :namespace + + t.string :username + t.text :encrypted_password + t.string :encrypted_password_iv + + t.text :encrypted_token + t.string :encrypted_token_iv + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_gcp_providers do |t| + t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + + t.integer :status + t.text :status_reason + + t.string :project_id, null: false + t.string :cluster_zone, null: false + t.string :cluster_name, null: false + t.integer :cluster_size, null: false + t.string :machine_type + t.string :operation_id + + t.string :endpoint + + t.text :encrypted_access_token + t.string :encrypted_access_token_iv + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + end +end -- cgit v1.2.1 From 1e78c627d4c6630df3bbfd4e905018314d692b6d Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 23 Oct 2017 10:17:31 +0300 Subject: explicitly specify search for hidden element [ci-skip] --- spec/features/groups_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 862823d862e..563e8a65b6e 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -65,7 +65,7 @@ feature 'Group' do end it 'updates the team URL on graph path update', :js do - out_span = find('span[data-bind-out="create_chat_team"]') + out_span = find('span[data-bind-out="create_chat_team"]', visible: false) expect(out_span.text).to be_empty -- cgit v1.2.1 From d0cff7f5855f91b5479f9fdaa39d8d95ec691a9e Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Mon, 23 Oct 2017 11:36:35 +0300 Subject: This works --- app/controllers/projects/clusters_controller.rb | 26 ++++--- app/models/clusters/cluster.rb | 52 ++++++++------ app/models/clusters/cluster_project.rb | 6 -- app/models/clusters/platforms/kubernetes.rb | 39 +++++----- app/models/clusters/project.rb | 8 +++ app/models/clusters/providers/gcp.rb | 29 ++++---- app/models/project.rb | 4 +- app/policies/clusters/cluster_policy.rb | 12 ++++ app/policies/gcp/cluster_policy.rb | 12 ---- app/presenters/clusters/cluster_presenter.rb | 9 +++ app/presenters/gcp/cluster_presenter.rb | 9 --- app/services/clusters/create_service.rb | 35 +++++++-- .../clusters/gcp/fetch_operation_service.rb | 6 +- .../clusters/gcp/finalize_creation_service.rb | 38 +++++----- app/services/clusters/gcp/provision_service.rb | 54 +++++++------- .../gcp/verify_provision_status_service.rb | 14 ++-- app/validators/cluster_name_validator.rb | 24 +++++++ app/views/projects/clusters/_form.html.haml | 44 ++++++------ app/views/projects/clusters/show.html.haml | 6 +- app/workers/cluster_provision_worker.rb | 2 +- app/workers/wait_for_cluster_creation_worker.rb | 2 +- db/migrate/20171013094327_create_clusters.rb | 66 ----------------- ...1013094327_create_new_clusters_architectures.rb | 66 +++++++++++++++++ ...cp_clusters_to_new_clusters_architectures.rb.rb | 84 ++++++++++++++++++++++ db/schema.rb | 61 +++++++++++++++- lib/gitlab/gcp/model.rb | 13 ---- spec/factories/gcp/cluster.rb | 68 +++++++++--------- 27 files changed, 496 insertions(+), 293 deletions(-) delete mode 100644 app/models/clusters/cluster_project.rb create mode 100644 app/models/clusters/project.rb create mode 100644 app/policies/clusters/cluster_policy.rb delete mode 100644 app/policies/gcp/cluster_policy.rb create mode 100644 app/presenters/clusters/cluster_presenter.rb delete mode 100644 app/presenters/gcp/cluster_presenter.rb create mode 100644 app/validators/cluster_name_validator.rb delete mode 100644 db/migrate/20171013094327_create_clusters.rb create mode 100644 db/migrate/20171013094327_create_new_clusters_architectures.rb create mode 100644 db/migrate/20171013104327_migrate_gcp_clusters_to_new_clusters_architectures.rb.rb delete mode 100644 lib/gitlab/gcp/model.rb diff --git a/app/controllers/projects/clusters_controller.rb b/app/controllers/projects/clusters_controller.rb index 0679d8c69f0..c07d955f148 100644 --- a/app/controllers/projects/clusters_controller.rb +++ b/app/controllers/projects/clusters_controller.rb @@ -27,11 +27,17 @@ class Projects::ClustersController < Projects::ApplicationController end def new - @cluster = project.build_cluster + @cluster = Clusters::Cluster.new( + platform_type: :kubernetes, + provider_type: :gcp).tap do |cluster| + cluster.build_provider_gcp + cluster.build_platform_kubernetes + cluster.projects << project + end end def create - @cluster = Ci::CreateService + @cluster = Clusters::CreateService .new(project, current_user, create_params) .execute(token_in_session) @@ -58,7 +64,7 @@ class Projects::ClustersController < Projects::ApplicationController end def update - Ci::UpdateClusterService + Clusters::UpdateService .new(project, current_user, update_params) .execute(cluster) @@ -89,16 +95,16 @@ class Projects::ClustersController < Projects::ApplicationController def create_params params.require(:cluster).permit( :enabled, + :name, :platform_type, :provider_type, - kubernetes_platform: [ + platform_kubernetes_attributes: [ :namespace ], - gcp_provider: [ - :project_id, - :cluster_zone, - :cluster_name, - :cluster_size, + provider_gcp_attributes: [ + :gcp_project_id, + :zone, + :num_nodes, :machine_type ]) end @@ -106,7 +112,7 @@ class Projects::ClustersController < Projects::ApplicationController def update_params params.require(:cluster).permit( :enabled, - kubernetes_platform: [ + platform_kubernetes_attributes: [ :namespace ]) end diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index d7b13ac88f2..f1eedad8795 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -2,49 +2,46 @@ module Clusters class Cluster < ActiveRecord::Base include Presentable + self.table_name = 'clusters' + belongs_to :user - belongs_to :service - enum :platform_type { + enum platform_type: { kubernetes: 1 } - enum :provider_type { + enum provider_type: { user: 0, gcp: 1 } - has_many :cluster_projects - has_many :projects, through: :cluster_projects + has_many :cluster_projects, class_name: 'Clusters::Project' + has_many :projects, through: :cluster_projects, class_name: '::Project' - has_one :gcp_provider - has_one :kubernetes_platform + has_one :provider_gcp, class_name: 'Clusters::Providers::Gcp' + has_one :platform_kubernetes, class_name: 'Clusters::Platforms::Kubernetes' - accepts_nested_attributes_for :gcp_provider - accepts_nested_attributes_for :kubernetes_platform + accepts_nested_attributes_for :provider_gcp + accepts_nested_attributes_for :platform_kubernetes - validates :kubernetes_platform, presence: true, if: :kubernetes? - validates :gcp_provider, presence: true, if: :gcp? + validates :name, cluster_name: true validate :restrict_modification, on: :update delegate :status, to: :provider, allow_nil: true delegate :status_reason, to: :provider, allow_nil: true - - def restrict_modification - if provider&.on_creation? - errors.add(:base, "cannot modify during creation") - return false - end - - true - end + delegate :status_name, to: :provider, allow_nil: true + delegate :on_creation?, to: :provider, allow_nil: true def provider - return gcp_provider if gcp? + return provider_gcp if gcp? end def platform - return kubernetes_platform if kubernetes? + return platform_kubernetes if kubernetes? + end + + def project + first_project end def first_project @@ -52,5 +49,16 @@ module Clusters @first_project = projects.first end + + private + + def restrict_modification + if provider&.on_creation? + errors.add(:base, "cannot modify during creation") + return false + end + + true + end end end diff --git a/app/models/clusters/cluster_project.rb b/app/models/clusters/cluster_project.rb deleted file mode 100644 index 7b139c2bb08..00000000000 --- a/app/models/clusters/cluster_project.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Clusters - class ClusterProject < ActiveRecord::Base - belongs_to :cluster - belongs_to :project - end -end diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index aed6f733487..d9f8927f7cc 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -4,11 +4,13 @@ module Clusters include Gitlab::Kubernetes include ReactiveCaching + self.table_name = 'cluster_platforms_kubernetes' + TEMPLATE_PLACEHOLDER = 'Kubernetes namespace'.freeze - self.reactive_cache_key = ->(service) { [service.class.model_name.singular, service.project_id] } + self.reactive_cache_key = ->(kubernetes) { [kubernetes.class.model_name.singular, kubernetes.cluster_id] } - belongs_to :cluster + belongs_to :cluster, inverse_of: :platform_kubernetes, class_name: 'Clusters::Cluster' attr_encrypted :password, mode: :per_attribute_iv, @@ -28,8 +30,8 @@ module Clusters message: Gitlab::Regex.kubernetes_namespace_regex_message } - validates :api_url, url: true, presence: true - validates :token, presence: true + validates :api_url, url: true, presence: true, on: :update + validates :token, presence: true, on: :update after_save :clear_reactive_cache! @@ -53,9 +55,9 @@ module Clusters { key: 'KUBECONFIG', value: config, public: false, file: true } ] - if ca_pem.present? - variables << { key: 'KUBE_CA_PEM', value: ca_pem, public: true } - variables << { key: 'KUBE_CA_PEM_FILE', value: ca_pem, public: true, file: true } + if ca_cert.present? + variables << { key: 'KUBE_CA_PEM', value: ca_cert, public: true } + variables << { key: 'KUBE_CA_PEM_FILE', value: ca_cert, public: true, file: true } end variables @@ -76,7 +78,7 @@ module Clusters # Caches resources in the namespace so other calls don't need to block on # network access def calculate_reactive_cache - return unless active? && project && !project.pending_delete? + return unless active? && cluster.project && !cluster.project.pending_delete? # We may want to cache extra things in the future { pods: read_pods } @@ -87,15 +89,16 @@ module Clusters url: api_url, namespace: actual_namespace, token: token, - ca_pem: ca_pem) + ca_pem: ca_cert) end def namespace_placeholder default_namespace || TEMPLATE_PLACEHOLDER end - def default_namespace - "#{cluster.first_project.path}-#{cluster.first_project.id}" if cluster.first_project + def default_namespace(project = nil) + project ||= cluster&.project + "#{project.path}-#{project.id}" if project end def read_secrets @@ -120,9 +123,9 @@ module Clusters def kubeclient_ssl_options opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER } - if ca_pem.present? + if ca_cert.present? opts[:cert_store] = OpenSSL::X509::Store.new - opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_pem)) + opts[:cert_store].add_cert(OpenSSL::X509::Certificate.new(ca_cert)) end opts @@ -131,7 +134,11 @@ module Clusters private def build_kubeclient!(api_path: 'api', api_version: 'v1') - raise "Incomplete settings" unless api_url && actual_namespace && token + raise "Incomplete settings" unless api_url && actual_namespace + + unless (username && password) || token + raise "Either username/password or token is required to access API" + end ::Kubeclient::Client.new( join_api_url(api_path), @@ -143,7 +150,7 @@ module Clusters end def kubeclient_auth_options - return { username: username, password: password } if username + return { username: username, password: password } if username && password return { bearer_token: token } if token end @@ -159,7 +166,7 @@ module Clusters def terminal_auth { token: token, - ca_pem: ca_pem, + ca_pem: ca_cert, max_session_time: current_application_settings.terminal_max_session_time } end diff --git a/app/models/clusters/project.rb b/app/models/clusters/project.rb new file mode 100644 index 00000000000..69088100420 --- /dev/null +++ b/app/models/clusters/project.rb @@ -0,0 +1,8 @@ +module Clusters + class Project < ActiveRecord::Base + self.table_name = 'cluster_projects' + + belongs_to :cluster, inverse_of: :projects, class_name: 'Clusters::Cluster' + belongs_to :project, inverse_of: :project, class_name: 'Project' + end +end diff --git a/app/models/clusters/providers/gcp.rb b/app/models/clusters/providers/gcp.rb index 5d4618cfe87..e4f109d2794 100644 --- a/app/models/clusters/providers/gcp.rb +++ b/app/models/clusters/providers/gcp.rb @@ -1,10 +1,12 @@ module Clusters module Providers class Gcp < ActiveRecord::Base - belongs_to :cluster + self.table_name = 'cluster_providers_gcp' - default_value_for :cluster_zone, 'us-central1-a' - default_value_for :cluster_size, 3 + belongs_to :cluster, inverse_of: :provider_gcp, class_name: 'Clusters::Cluster' + + default_value_for :zone, 'us-central1-a' + default_value_for :num_nodes, 3 default_value_for :machine_type, 'n1-standard-4' attr_encrypted :access_token, @@ -12,23 +14,16 @@ module Clusters key: Gitlab::Application.secrets.db_key_base, algorithm: 'aes-256-cbc' - validates :project_id, + validates :gcp_project_id, length: 1..63, format: { with: Gitlab::Regex.kubernetes_namespace_regex, message: Gitlab::Regex.kubernetes_namespace_regex_message } - validates :cluster_name, - length: 1..63, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - validates :cluster_zone, presence: true + validates :zone, presence: true - validates :cluster_size, + validates :num_nodes, presence: true, numericality: { only_integer: true, @@ -54,9 +49,13 @@ module Clusters end before_transition any => [:errored, :created] do |provider| - provider.token = nil + provider.access_token = nil provider.operation_id = nil - provider.save! + end + + before_transition any => [:creating] do |provider, transition| + operation_id = transition.args.first + provider.operation_id = operation_id if operation_id end before_transition any => [:errored] do |provider, transition| diff --git a/app/models/project.rb b/app/models/project.rb index bc263b63881..70c75edcda3 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -178,8 +178,8 @@ class Project < ActiveRecord::Base has_one :project_feature, inverse_of: :project has_one :statistics, class_name: 'ProjectStatistics' - has_many :cluster_projects, class_name: 'Clusters::ClusterProject' - has_one :cluster, through: :cluster_projects + has_one :cluster_project, class_name: 'Clusters::Project' + has_one :cluster, through: :cluster_project, class_name: 'Clusters::Cluster' # Container repositories need to remove data from the container registry, # which is not managed by the DB. Hence we're still using dependent: :destroy diff --git a/app/policies/clusters/cluster_policy.rb b/app/policies/clusters/cluster_policy.rb new file mode 100644 index 00000000000..1f7c13072b9 --- /dev/null +++ b/app/policies/clusters/cluster_policy.rb @@ -0,0 +1,12 @@ +module Clusters + class ClusterPolicy < BasePolicy + alias_method :cluster, :subject + + delegate { cluster.project } + + rule { can?(:master_access) }.policy do + enable :update_cluster + enable :admin_cluster + end + end +end diff --git a/app/policies/gcp/cluster_policy.rb b/app/policies/gcp/cluster_policy.rb deleted file mode 100644 index e77173ea6e1..00000000000 --- a/app/policies/gcp/cluster_policy.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Gcp - class ClusterPolicy < BasePolicy - alias_method :cluster, :subject - - delegate { @subject.project } - - rule { can?(:master_access) }.policy do - enable :update_cluster - enable :admin_cluster - end - end -end diff --git a/app/presenters/clusters/cluster_presenter.rb b/app/presenters/clusters/cluster_presenter.rb new file mode 100644 index 00000000000..01cb59d0d44 --- /dev/null +++ b/app/presenters/clusters/cluster_presenter.rb @@ -0,0 +1,9 @@ +module Clusters + class ClusterPresenter < Gitlab::View::Presenter::Delegated + presents :cluster + + def gke_cluster_url + "https://console.cloud.google.com/kubernetes/clusters/details/#{provider.zone}/#{name}" if gcp? + end + end +end diff --git a/app/presenters/gcp/cluster_presenter.rb b/app/presenters/gcp/cluster_presenter.rb deleted file mode 100644 index f7908f92a37..00000000000 --- a/app/presenters/gcp/cluster_presenter.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gcp - class ClusterPresenter < Gitlab::View::Presenter::Delegated - presents :cluster - - def gke_cluster_url - "https://console.cloud.google.com/kubernetes/clusters/details/#{gcp_cluster_zone}/#{gcp_cluster_name}" - end - end -end diff --git a/app/services/clusters/create_service.rb b/app/services/clusters/create_service.rb index 5429bc21256..3f458e25c14 100644 --- a/app/services/clusters/create_service.rb +++ b/app/services/clusters/create_service.rb @@ -1,14 +1,39 @@ module Clusters class CreateService < BaseService - def execute(access_token) - params['gcp_machine_type'] ||= GoogleApi::CloudPlatform::Client::DEFAULT_MACHINE_TYPE + attr_reader :access_token - cluster_params = - params.merge(user: current_user) + def execute(access_token) + @access_token = access_token - project.create_cluster(cluster_params).tap do |cluster| + create_cluster.tap do |cluster| ClusterProvisionWorker.perform_async(cluster.id) if cluster.persisted? end end + + private + + def create_cluster + cluster = nil + + ActiveRecord::Base.transaction do + cluster = Clusters::Cluster.create!(cluster_params) + cluster.projects << project + end + + cluster + rescue ActiveRecord::RecordInvalid => e + e.record + end + + def cluster_params + return @cluster_params if defined?(@cluster_params) + + params[:provider_gcp_attributes][:machine_type] ||= + GoogleApi::CloudPlatform::Client::DEFAULT_MACHINE_TYPE + + params[:provider_gcp_attributes][:access_token] ||= access_token + + @cluster_params = params.merge(user: current_user) + end end end diff --git a/app/services/clusters/gcp/fetch_operation_service.rb b/app/services/clusters/gcp/fetch_operation_service.rb index 013225efac4..a4cd3ca5c11 100644 --- a/app/services/clusters/gcp/fetch_operation_service.rb +++ b/app/services/clusters/gcp/fetch_operation_service.rb @@ -3,13 +3,13 @@ module Clusters class FetchOperationService def execute(provider) operation = provider.api_client.projects_zones_operations( - provider.project_id, - provider.cluster_zone, + provider.gcp_project_id, + provider.zone, provider.operation_id) yield(operation) if block_given? rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") + provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") end end end diff --git a/app/services/clusters/gcp/finalize_creation_service.rb b/app/services/clusters/gcp/finalize_creation_service.rb index b536285b368..9f257bd0e9a 100644 --- a/app/services/clusters/gcp/finalize_creation_service.rb +++ b/app/services/clusters/gcp/finalize_creation_service.rb @@ -7,15 +7,14 @@ module Clusters @provider = provider configure_provider - configure_kubernetes_platform - request_kuberenetes_platform_token + configure_kubernetes ActiveRecord::Base.transaction do - kubernetes_platform.update! + kubernetes.save! provider.make_created! end rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") + cluster.make_errored!("Failed to request to CloudPlatform; #{e.message}") rescue ActiveRecord::RecordInvalid => e cluster.make_errored!("Failed to configure GKE Cluster: #{e.message}") end @@ -26,23 +25,20 @@ module Clusters provider.endpoint = gke_cluster.endpoint end - def configure_kubernetes_platform - kubernetes_platform = cluster.kubernetes_platform - kubernetes_platform.api_url = 'https://' + endpoint - kubernetes_platform.ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) - kubernetes_platform.username = gke_cluster.master_auth.username - kubernetes_platform.password = gke_cluster.master_auth.password + def configure_kubernetes + kubernetes.api_url = 'https://' + gke_cluster.endpoint + kubernetes.ca_cert = Base64.decode64(gke_cluster.master_auth.cluster_ca_certificate) + kubernetes.username = gke_cluster.master_auth.username + kubernetes.password = gke_cluster.master_auth.password + kubernetes.token = request_kuberenetes_token end - def request_kuberenetes_platform_token - kubernetes_platform.read_secrets.each do |secret| + def request_kuberenetes_token + kubernetes.read_secrets.each do |secret| name = secret.dig('metadata', 'name') if /default-token/ =~ name token_base64 = secret.dig('data', 'token') - if token_base64 - kubernetes_platform.token = Base64.decode64(token_base64) - break - end + return Base64.decode64(token_base64) if token_base64 end end end @@ -50,16 +46,16 @@ module Clusters def gke_cluster @gke_cluster ||= provider.api_client.projects_zones_clusters_get( provider.gcp_project_id, - provider.gcp_cluster_zone, - provider.gcp_cluster_name) + provider.zone, + cluster.name) end def cluster - provider.cluster + @cluster ||= provider.cluster end - def kubernetes_platform - cluster.kubernetes_platform + def kubernetes + @kubernetes ||= cluster.platform_kubernetes end end end diff --git a/app/services/clusters/gcp/provision_service.rb b/app/services/clusters/gcp/provision_service.rb index 269705000ac..8ec81e22203 100644 --- a/app/services/clusters/gcp/provision_service.rb +++ b/app/services/clusters/gcp/provision_service.rb @@ -6,43 +6,41 @@ module Clusters def execute(provider) @provider = provider - unless operation.status == 'RUNNING' || operation.status == 'PENDING' - return provider.make_errored!("Operation status is unexpected; #{operation.status_message}") + get_operation_id do |operation_id| + if provider.make_creating(operation_id) + WaitForClusterCreationWorker.perform_in( + Clusters::Gcp::VerifyProvisionStatusService::INITIAL_INTERVAL, + provider.id) + else + provider.make_errored!("Failed to update provider record; #{provider.errors}") + end end + end - provider.operation_id = operation_id + private - unless provider.operation_id - return provider.make_errored!('Can not find operation_id from self_link') - end + def get_operation_id + operation = provider.api_client.projects_zones_clusters_create( + provider.gcp_project_id, + provider.zone, + provider.cluster.name, + provider.num_nodes, + machine_type: provider.machine_type) - if provider.make_creating - WaitForClusterCreationWorker.perform_in( - WaitForClusterCreationWorker::INITIAL_INTERVAL, provider.id) - else - return provider.make_errored!("Failed to update provider record; #{provider.errors}") + unless operation.status == 'PENDING' || operation.status == 'RUNNING' + return provider.make_errored!("Operation status is unexpected; #{operation.status_message}") end - rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e - return provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") - end - private + operation_id = provider.api_client.parse_operation_id(operation.self_link) - def operation_id - api_client.parse_operation_id(operation.self_link) - end + unless operation_id + return provider.make_errored!('Can not find operation_id from self_link') + end - def operation - @operation ||= api_client.projects_zones_providers_create( - provider.project_id, - provider.provider_zone, - provider.provider_name, - provider.provider_size, - machine_type: provider.machine_type) - end + yield(operation_id) - def api_client - provider.api_client + rescue Google::Apis::ServerError, Google::Apis::ClientError, Google::Apis::AuthorizationError => e + provider.make_errored!("Failed to request to CloudPlatform; #{e.message}") end end end diff --git a/app/services/clusters/gcp/verify_provision_status_service.rb b/app/services/clusters/gcp/verify_provision_status_service.rb index 466ea986516..bc33756f27c 100644 --- a/app/services/clusters/gcp/verify_provision_status_service.rb +++ b/app/services/clusters/gcp/verify_provision_status_service.rb @@ -12,7 +12,7 @@ module Clusters request_operation do |operation| case operation.status - when 'RUNNING' + when 'PENDING', 'RUNNING' continue_creation(operation) when 'DONE' finalize_creation @@ -25,11 +25,15 @@ module Clusters private def continue_creation(operation) - if TIMEOUT < Time.now.utc - operation.start_time.to_time.utc - return provider.make_errored!("Cluster creation time exceeds timeout; #{TIMEOUT}") + if elapsed_time_from_creation(operation) < TIMEOUT + WaitForClusterCreationWorker.perform_in(EAGER_INTERVAL, provider.cluster_id) + else + provider.make_errored!("Cluster creation time exceeds timeout; #{TIMEOUT}") end + end - WaitForClusterCreationWorker.perform_in(EAGER_INTERVAL, provider.cluster_id) + def elapsed_time_from_creation(operation) + Time.now.utc - operation.start_time.to_time.utc end def finalize_creation @@ -37,7 +41,7 @@ module Clusters end def request_operation(&blk) - Clusters::FetchGcpOperationService.new.execute(provider, &blk) + Clusters::Gcp::FetchOperationService.new.execute(provider, &blk) end end end diff --git a/app/validators/cluster_name_validator.rb b/app/validators/cluster_name_validator.rb new file mode 100644 index 00000000000..6c9850af30f --- /dev/null +++ b/app/validators/cluster_name_validator.rb @@ -0,0 +1,24 @@ +# ClusterNameValidator +# +# Custom validator for ClusterName. +class ClusterNameValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + if record.user? + unless value.present? + record.errors.add(attribute, " has to be present") + end + elsif record.gcp? + if record.persisted? && record.name != value + record.errors.add(attribute, " can not be changed because it's synchronized with provider") + end + + unless value.length >= 1 && value.length <= 63 + record.errors.add(attribute, " is invalid syntax") + end + + unless value =~ Gitlab::Regex.kubernetes_namespace_regex + record.errors.add(attribute, Gitlab::Regex.kubernetes_namespace_regex_message) + end + end + end +end diff --git a/app/views/projects/clusters/_form.html.haml b/app/views/projects/clusters/_form.html.haml index 371cdb1e403..b3020513abf 100644 --- a/app/views/projects/clusters/_form.html.haml +++ b/app/views/projects/clusters/_form.html.haml @@ -4,34 +4,38 @@ - link_to_help_page = link_to(s_('ClusterIntegration|help page'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') = s_('ClusterIntegration|Read our %{link_to_help_page} on cluster integration.').html_safe % { link_to_help_page: link_to_help_page} - = form_for [@project.namespace.becomes(Namespace), @project, @cluster] do |field| + = form_for @cluster, url: namespace_project_clusters_path(@project.namespace, @project, @cluster), as: :cluster do |field| + = field.hidden_field :platform_type, :value => 'kubernetes' + = field.hidden_field :provider_type, :value => 'gcp' = form_errors(@cluster) .form-group - = field.label :gcp_cluster_name, s_('ClusterIntegration|Cluster name') - = field.text_field :gcp_cluster_name, class: 'form-control' + = field.label :name, s_('ClusterIntegration|Cluster name') + = field.text_field :name, class: 'form-control' - .form-group - = field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project ID') - = link_to(s_('ClusterIntegration|See your projects'), 'https://console.cloud.google.com/home/dashboard', target: '_blank', rel: 'noopener noreferrer') - = field.text_field :gcp_project_id, class: 'form-control' + = field.fields_for :provider_gcp, @cluster.provider_gcp do |provider_gcp_field| + .form-group + = provider_gcp_field.label :gcp_project_id, s_('ClusterIntegration|Google Cloud Platform project ID') + = link_to(s_('ClusterIntegration|See your projects'), 'https://console.cloud.google.com/home/dashboard', target: '_blank', rel: 'noopener noreferrer') + = provider_gcp_field.text_field :gcp_project_id, class: 'form-control' - .form-group - = field.label :gcp_cluster_zone, s_('ClusterIntegration|Zone') - = link_to(s_('ClusterIntegration|See zones'), 'https://cloud.google.com/compute/docs/regions-zones/regions-zones', target: '_blank', rel: 'noopener noreferrer') - = field.text_field :gcp_cluster_zone, class: 'form-control', placeholder: 'us-central1-a' + .form-group + = provider_gcp_field.label :zone, s_('ClusterIntegration|Zone') + = link_to(s_('ClusterIntegration|See zones'), 'https://cloud.google.com/compute/docs/regions-zones/regions-zones', target: '_blank', rel: 'noopener noreferrer') + = provider_gcp_field.text_field :zone, class: 'form-control', placeholder: 'us-central1-a' - .form-group - = field.label :gcp_cluster_size, s_('ClusterIntegration|Number of nodes') - = field.text_field :gcp_cluster_size, class: 'form-control', placeholder: '3' + .form-group + = provider_gcp_field.label :num_nodes, s_('ClusterIntegration|Number of nodes') + = provider_gcp_field.text_field :num_nodes, class: 'form-control', placeholder: '3' - .form-group - = field.label :gcp_machine_type, s_('ClusterIntegration|Machine type') - = link_to(s_('ClusterIntegration|See machine types'), 'https://cloud.google.com/compute/docs/machine-types', target: '_blank', rel: 'noopener noreferrer') - = field.text_field :gcp_machine_type, class: 'form-control', placeholder: 'n1-standard-4' + .form-group + = provider_gcp_field.label :machine_type, s_('ClusterIntegration|Machine type') + = link_to(s_('ClusterIntegration|See machine types'), 'https://cloud.google.com/compute/docs/machine-types', target: '_blank', rel: 'noopener noreferrer') + = provider_gcp_field.text_field :machine_type, class: 'form-control', placeholder: 'n1-standard-4' + = field.fields_for :platform_kubernetes, @cluster.platform_kubernetes do |platform_kubernetes_field| .form-group - = field.label :project_namespace, s_('ClusterIntegration|Project namespace (optional, unique)') - = field.text_field :project_namespace, class: 'form-control', placeholder: @cluster.project_namespace_placeholder + = platform_kubernetes_field.label :namespace, s_('ClusterIntegration|Project namespace (optional, unique)') + = platform_kubernetes_field.text_field :namespace, class: 'form-control', placeholder: @cluster.platform_kubernetes.default_namespace(@project) .form-group = field.submit s_('ClusterIntegration|Create cluster'), class: 'btn btn-save' diff --git a/app/views/projects/clusters/show.html.haml b/app/views/projects/clusters/show.html.haml index ff76abc3553..49adae82454 100644 --- a/app/views/projects/clusters/show.html.haml +++ b/app/views/projects/clusters/show.html.haml @@ -33,7 +33,7 @@ - else = s_('ClusterIntegration|Cluster integration is disabled for this project.') - = form_for [@project.namespace.becomes(Namespace), @project, @cluster] do |field| + = form_for @cluster, url: namespace_project_cluster_path(@project.namespace, @project, @cluster), as: :cluster do |field| = form_errors(@cluster) .form-group.append-bottom-20 %label.append-bottom-10 @@ -62,9 +62,9 @@ %label.append-bottom-10{ for: 'cluter-name' } = s_('ClusterIntegration|Cluster name') .input-group - %input.form-control.cluster-name{ value: @cluster.gcp_cluster_name, disabled: true } + %input.form-control.cluster-name{ value: @cluster.name, disabled: true } %span.input-group-addon.clipboard-addon - = clipboard_button(text: @cluster.gcp_cluster_name, title: s_('ClusterIntegration|Copy cluster name')) + = clipboard_button(text: @cluster.name, title: s_('ClusterIntegration|Copy cluster name')) %section.settings#js-cluster-advanced-settings .settings-header diff --git a/app/workers/cluster_provision_worker.rb b/app/workers/cluster_provision_worker.rb index 79f0d73c396..0929fffc444 100644 --- a/app/workers/cluster_provision_worker.rb +++ b/app/workers/cluster_provision_worker.rb @@ -4,7 +4,7 @@ class ClusterProvisionWorker def perform(cluster_id) Clusters::Cluster.find_by_id(cluster_id).try do |cluster| - cluster.gcp_provider.try do |provider| + cluster.provider_gcp.try do |provider| Clusters::Gcp::ProvisionService.new.execute(provider) end end diff --git a/app/workers/wait_for_cluster_creation_worker.rb b/app/workers/wait_for_cluster_creation_worker.rb index d8c42c6bd55..b2f04869636 100644 --- a/app/workers/wait_for_cluster_creation_worker.rb +++ b/app/workers/wait_for_cluster_creation_worker.rb @@ -4,7 +4,7 @@ class WaitForClusterCreationWorker def perform(cluster_id) Clusters::Cluster.find_by_id(cluster_id).try do |cluster| - cluster.gcp_provider.try do |provider| + cluster.provider_gcp.try do |provider| Clusters::Gcp::VerifyProvisionStatusService.new.execute(provider) end end diff --git a/db/migrate/20171013094327_create_clusters.rb b/db/migrate/20171013094327_create_clusters.rb deleted file mode 100644 index ad30181f984..00000000000 --- a/db/migrate/20171013094327_create_clusters.rb +++ /dev/null @@ -1,66 +0,0 @@ -class CreateGcpClusters < ActiveRecord::Migration - DOWNTIME = false - - def change - create_table :clusters do |t| - t.references :user, foreign_key: { on_delete: :nullify } - - t.boolean :enabled, default: true - - t.integer :provider_type, null: false - t.integer :platform_type, null: false - - t.datetime_with_timezone :created_at, null: false - t.datetime_with_timezone :updated_at, null: false - end - - create_table :cluster_projects do |t| - t.references :project, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } - t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } - - t.datetime_with_timezone :created_at, null: false - t.datetime_with_timezone :updated_at, null: false - end - - create_table :cluster_kubernetes_platforms do |t| - t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } - - t.string :api_url - t.text :ca_cert - - t.string :namespace - - t.string :username - t.text :encrypted_password - t.string :encrypted_password_iv - - t.text :encrypted_token - t.string :encrypted_token_iv - - t.datetime_with_timezone :created_at, null: false - t.datetime_with_timezone :updated_at, null: false - end - - create_table :cluster_gcp_providers do |t| - t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } - - t.integer :status - t.text :status_reason - - t.string :project_id, null: false - t.string :cluster_zone, null: false - t.string :cluster_name, null: false - t.integer :cluster_size, null: false - t.string :machine_type - t.string :operation_id - - t.string :endpoint - - t.text :encrypted_access_token - t.string :encrypted_access_token_iv - - t.datetime_with_timezone :created_at, null: false - t.datetime_with_timezone :updated_at, null: false - end - end -end diff --git a/db/migrate/20171013094327_create_new_clusters_architectures.rb b/db/migrate/20171013094327_create_new_clusters_architectures.rb new file mode 100644 index 00000000000..35df8cb4a60 --- /dev/null +++ b/db/migrate/20171013094327_create_new_clusters_architectures.rb @@ -0,0 +1,66 @@ +class CreateNewClustersArchitectures < ActiveRecord::Migration + DOWNTIME = false + + def change + create_table :clusters do |t| + t.references :user, foreign_key: { on_delete: :nullify } + + t.boolean :enabled, default: true + t.string :name, null: false # If manual, read-write. If gcp, read-only. + + t.integer :provider_type, null: false + t.integer :platform_type, null: false + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_projects do |t| + t.references :project, null: false, index: true, foreign_key: { on_delete: :cascade } + t.references :cluster, null: false, index: true, foreign_key: { on_delete: :cascade } + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_platforms_kubernetes do |t| + t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + + t.string :api_url + t.text :ca_cert + + t.string :namespace + + t.string :username + t.text :encrypted_password + t.string :encrypted_password_iv + + t.text :encrypted_token + t.string :encrypted_token_iv + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + + create_table :cluster_providers_gcp do |t| + t.references :cluster, null: false, index: { unique: true }, foreign_key: { on_delete: :cascade } + + t.integer :status + t.text :status_reason + + t.string :gcp_project_id, null: false + t.string :zone, null: false + t.integer :num_nodes, null: false + t.string :machine_type + t.string :operation_id + + t.string :endpoint + + t.text :encrypted_access_token + t.string :encrypted_access_token_iv + + t.datetime_with_timezone :created_at, null: false + t.datetime_with_timezone :updated_at, null: false + end + end +end diff --git a/db/migrate/20171013104327_migrate_gcp_clusters_to_new_clusters_architectures.rb.rb b/db/migrate/20171013104327_migrate_gcp_clusters_to_new_clusters_architectures.rb.rb new file mode 100644 index 00000000000..5510b036d24 --- /dev/null +++ b/db/migrate/20171013104327_migrate_gcp_clusters_to_new_clusters_architectures.rb.rb @@ -0,0 +1,84 @@ +class MigrateGcpClustersToNewClustersArchitectures < ActiveRecord::Migration + DOWNTIME = false + + def up + # TODO: Chnage to something reaistic + ActiveRecord::Base.connection.select_rows('SELECT * from gcp_clusters;').each do |old_cluster| + id = old_cluster[0] + project_id = old_cluster[1] + user_id = old_cluster[2] + service_id = old_cluster[3] + status = old_cluster[4] + gcp_cluster_size = old_cluster[5] + created_at = old_cluster[6] + updated_at = old_cluster[7] + enabled = old_cluster[8] + status_reason = old_cluster[9] + project_namespace = old_cluster[10] + endpoint = old_cluster[11] + ca_cert = old_cluster[12] + encrypted_kubernetes_token = old_cluster[13] + encrypted_kubernetes_token_iv = old_cluster[14] + username = old_cluster[15] + encrypted_password = old_cluster[16] + encrypted_password_iv = old_cluster[17] + gcp_project_id = old_cluster[18] + gcp_cluster_zone = old_cluster[19] + gcp_cluster_name = old_cluster[20] + gcp_machine_type = old_cluster[21] + gcp_operation_id = old_cluster[22] + encrypted_gcp_token = old_cluster[23] + encrypted_gcp_token_iv = old_cluster[24] + + cluster = Clusters::Cluster.create!( + user_id: user_id, + enabled: enabled, + name: gcp_cluster_name, + provider_type: :gcp, + platform_type: :kubernetes, + created_at: created_at, + updated_at: updated_at) + + Clusters::Project.create!( + cluster: cluster, + project_id: project_id, + created_at: created_at, + updated_at: updated_at) + + Clusters::Platforms::Kubernetes.create!( + cluster: cluster, + api_url: 'https://' + endpoint, + ca_cert: ca_cert, + namespace: project_namespace, + username: username, + encrypted_password: encrypted_password, + encrypted_password_iv: encrypted_password_iv, + encrypted_token: encrypted_kubernetes_token, + encrypted_token_iv: encrypted_kubernetes_token_iv, + created_at: created_at, + updated_at: updated_at) + + Clusters::Providers::Gcp.create!( + cluster: cluster, + status: status, + status_reason: status_reason, + gcp_project_id: gcp_project_id, + zone: gcp_cluster_zone, + num_nodes: gcp_cluster_size, + machine_type: gcp_machine_type, + operation_id: gcp_operation_id, + endpoint: endpoint, + encrypted_access_token: encrypted_gcp_token, + encrypted_access_token_iv: encrypted_gcp_token_iv, + created_at: created_at, + updated_at: updated_at) + end + end + + def down + Clusters::Cluster.delete_all + Clusters::Project.delete_all + Clusters::Providers::Gcp.delete_all + Clusters::Platforms::Kubernetes.delete_all + end +end diff --git a/db/schema.rb b/db/schema.rb index c2c04873d4d..65e8a3120a1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171012101043) do +ActiveRecord::Schema.define(version: 20171013104327) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -460,6 +460,60 @@ ActiveRecord::Schema.define(version: 20171012101043) do add_index "ci_variables", ["project_id", "key", "environment_scope"], name: "index_ci_variables_on_project_id_and_key_and_environment_scope", unique: true, using: :btree + create_table "cluster_platforms_kubernetes", force: :cascade do |t| + t.integer "cluster_id", null: false + t.string "api_url" + t.text "ca_cert" + t.string "namespace" + t.string "username" + t.text "encrypted_password" + t.string "encrypted_password_iv" + t.text "encrypted_token" + t.string "encrypted_token_iv" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "cluster_platforms_kubernetes", ["cluster_id"], name: "index_cluster_platforms_kubernetes_on_cluster_id", unique: true, using: :btree + + create_table "cluster_projects", force: :cascade do |t| + t.integer "project_id", null: false + t.integer "cluster_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "cluster_projects", ["cluster_id"], name: "index_cluster_projects_on_cluster_id", using: :btree + add_index "cluster_projects", ["project_id"], name: "index_cluster_projects_on_project_id", using: :btree + + create_table "cluster_providers_gcp", force: :cascade do |t| + t.integer "cluster_id", null: false + t.integer "status" + t.text "status_reason" + t.string "gcp_project_id", null: false + t.string "zone", null: false + t.integer "num_nodes", null: false + t.string "machine_type" + t.string "operation_id" + t.string "endpoint" + t.text "encrypted_access_token" + t.string "encrypted_access_token_iv" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "cluster_providers_gcp", ["cluster_id"], name: "index_cluster_providers_gcp_on_cluster_id", unique: true, using: :btree + + create_table "clusters", force: :cascade do |t| + t.integer "user_id" + t.boolean "enabled", default: true + t.string "name", null: false + t.integer "provider_type", null: false + t.integer "platform_type", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "container_repositories", force: :cascade do |t| t.integer "project_id", null: false t.string "name", null: false @@ -1808,6 +1862,11 @@ ActiveRecord::Schema.define(version: 20171012101043) do add_foreign_key "ci_triggers", "projects", name: "fk_e3e63f966e", on_delete: :cascade add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade add_foreign_key "ci_variables", "projects", name: "fk_ada5eb64b3", on_delete: :cascade + add_foreign_key "cluster_platforms_kubernetes", "clusters", on_delete: :cascade + add_foreign_key "cluster_projects", "clusters", on_delete: :cascade + add_foreign_key "cluster_projects", "projects", on_delete: :cascade + add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade + add_foreign_key "clusters", "users", on_delete: :nullify add_foreign_key "container_repositories", "projects" add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade diff --git a/lib/gitlab/gcp/model.rb b/lib/gitlab/gcp/model.rb deleted file mode 100644 index 195391f0e3c..00000000000 --- a/lib/gitlab/gcp/model.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module Gcp - module Model - def table_name_prefix - "gcp_" - end - - def model_name - @model_name ||= ActiveModel::Name.new(self, nil, self.name.split("::").last) - end - end - end -end diff --git a/spec/factories/gcp/cluster.rb b/spec/factories/gcp/cluster.rb index 630e40da888..5c062737ffc 100644 --- a/spec/factories/gcp/cluster.rb +++ b/spec/factories/gcp/cluster.rb @@ -1,38 +1,38 @@ -FactoryGirl.define do - factory :gcp_cluster, class: Gcp::Cluster do - project - user - enabled true - gcp_project_id 'gcp-project-12345' - gcp_cluster_name 'test-cluster' - gcp_cluster_zone 'us-central1-a' - gcp_cluster_size 1 - gcp_machine_type 'n1-standard-4' +# FactoryGirl.define do +# factory :gcp_cluster, class: Gcp::Cluster do +# project +# user +# enabled true +# gcp_project_id 'gcp-project-12345' +# gcp_cluster_name 'test-cluster' +# gcp_cluster_zone 'us-central1-a' +# gcp_cluster_size 1 +# gcp_machine_type 'n1-standard-4' - trait :with_kubernetes_service do - after(:create) do |cluster, evaluator| - create(:kubernetes_service, project: cluster.project).tap do |service| - cluster.update(service: service) - end - end - end +# trait :with_kubernetes_service do +# after(:create) do |cluster, evaluator| +# create(:kubernetes_service, project: cluster.project).tap do |service| +# cluster.update(service: service) +# end +# end +# end - trait :custom_project_namespace do - project_namespace 'sample-app' - end +# trait :custom_project_namespace do +# project_namespace 'sample-app' +# end - trait :created_on_gke do - status_event :make_created - endpoint '111.111.111.111' - ca_cert 'xxxxxx' - kubernetes_token 'xxxxxx' - username 'xxxxxx' - password 'xxxxxx' - end +# trait :created_on_gke do +# status_event :make_created +# endpoint '111.111.111.111' +# ca_cert 'xxxxxx' +# kubernetes_token 'xxxxxx' +# username 'xxxxxx' +# password 'xxxxxx' +# end - trait :errored do - status_event :make_errored - status_reason 'general error' - end - end -end +# trait :errored do +# status_event :make_errored +# status_reason 'general error' +# end +# end +# end -- cgit v1.2.1 From df20c6fe46c14905f90fa92bbc88529106382988 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 23 Oct 2017 13:54:10 +0300 Subject: add accept_confirm to spec --- spec/features/projects/members/user_requests_access_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 0fbe1ddb2a5..4eb36156812 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -60,7 +60,7 @@ feature 'Projects > Members > User requests access', :js do expect(project.requesters.exists?(user_id: user)).to be_truthy - click_link 'Withdraw Access Request' + accept_confirm { click_link 'Withdraw Access Request' } expect(project.requesters.exists?(user_id: user)).to be_falsey expect(page).to have_content 'Your access request to the project has been withdrawn.' -- cgit v1.2.1 From 04149dccab97aad4350cae9a6c6054b7de5c9850 Mon Sep 17 00:00:00 2001 From: Jose Ivan Vargas Date: Mon, 23 Oct 2017 13:55:15 +0300 Subject: Changed trigger click calls to click() --- spec/features/projects/import_export/import_file_spec.rb | 2 +- spec/features/projects/new_project_spec.rb | 4 ++-- spec/features/projects_spec.rb | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 026aa03f7cf..af125e1b9d3 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -94,6 +94,6 @@ feature 'Import/Export - project import integration test', :js do end def click_import_project_tab - find('#import-project-tab').trigger('click') + find('#import-project-tab').click end end diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 8e11cb94350..6f097ad16c7 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -15,7 +15,7 @@ feature 'New project' do expect(page).to have_content('Project path') expect(page).to have_content('Project name') - find('#import-project-tab').trigger('click') + find('#import-project-tab').click expect(page).to have_link('GitHub') expect(page).to have_link('Bitbucket') @@ -137,7 +137,7 @@ feature 'New project' do context 'Import project options', :js do before do visit new_project_path - find('#import-project-tab').trigger('click') + find('#import-project-tab').click end context 'from git repository url' do diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 3b01ed442bf..d7e46f3525f 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -13,8 +13,10 @@ feature 'Project' do end it "allows creation from templates", :js do - find('#create-from-template-tab').trigger('click') - find("##{template.name}").trigger('click') + find('#create-from-template-tab').click + page.execute_script( + "document.querySelector('##{template.name}').click()" + ) fill_in("project_path", with: template.name) page.within '#content-body' do -- cgit v1.2.1 From 3e5bfe5abd70f11224fa934f78a3e68f2038359a Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Mon, 23 Oct 2017 13:41:52 +0100 Subject: Prefer dispatcher glform init over global init --- app/assets/javascripts/dispatcher.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index eb576672d25..07535508d59 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -234,6 +234,7 @@ import DueDateSelectors from './due_date_select'; case 'groups:milestones:update': new ZenMode(); new DueDateSelectors(); + new GLForm($('.milestone-form'), false); break; case 'projects:compare:show': new gl.Diff(); -- cgit v1.2.1 From 1ae013dad5cca881e54e4c67f42748ed6580bfec Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Mon, 23 Oct 2017 13:37:47 +0100 Subject: Fix karma --- app/assets/javascripts/notes.js | 2 +- spec/javascripts/notes_spec.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index cf247a4c170..7f163e7e0e8 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -413,8 +413,8 @@ export default class Notes { return; } this.note_ids.push(noteEntity.id); - form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); + form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); row = form.length ? form.closest('tr') : $(`#${noteEntity.discussion_line_code}`); if (noteEntity.on_image) { diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 66c52611614..2514f7ea841 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -333,6 +333,7 @@ import '~/notes'; diff_discussion_html: false, }; $form = jasmine.createSpyObj('$form', ['closest', 'find']); + $form.length = 1; row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']); notes = jasmine.createSpyObj('notes', [ -- cgit v1.2.1 From b612bcfc64618906b5b11a245fb0aa2452d6c5dd Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 23 Oct 2017 12:19:56 +0300 Subject: implement basic request inspector for use in Capybara tests --- config/environments/test.rb | 1 + lib/gitlab/testing/request_inspector_middleware.rb | 59 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 lib/gitlab/testing/request_inspector_middleware.rb diff --git a/config/environments/test.rb b/config/environments/test.rb index 1edb6fd39b8..d09e51e766a 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,6 +1,7 @@ Rails.application.configure do # Make sure the middleware is inserted first in middleware chain config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestBlockerMiddleware') + config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestInspectorMiddleware') # Settings specified here will take precedence over those in config/application.rb diff --git a/lib/gitlab/testing/request_inspector_middleware.rb b/lib/gitlab/testing/request_inspector_middleware.rb new file mode 100644 index 00000000000..0ca21bd6a37 --- /dev/null +++ b/lib/gitlab/testing/request_inspector_middleware.rb @@ -0,0 +1,59 @@ +module Gitlab + module Testing + class RequestInspectorMiddleware + @@log_requests = Concurrent::AtomicBoolean.new(false) + @@logged_requests = Concurrent::Array.new + + # Resets the current request log and starts logging requests + def self.log_requests! + @@logged_requests.replace([]) + @@log_requests.value = true + end + + # Stops logging requests + def self.stop_logging! + @@log_requests.value = false + end + + def self.requests + @@logged_requests + end + + def initialize(app) + @app = app + end + + def call(env) + return @app.call(env) unless @@log_requests.true? + + url = env['REQUEST_URI'] + request_headers = env_http_headers(env) + status, headers, body = @app.call(env) + + log_response({ + url: url, + status_code: status, + request_headers: request_headers, + response_headers: headers + }) + + [status, headers, body] + end + + private + + def env_http_headers(env) + Hash[*env.select {|k,v| k.start_with? 'HTTP_'} + .collect {|k,v| [k.sub(/^HTTP_/, ''), v]} + .collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]} + .sort + .flatten] + end + + def log_response(response) + @@logged_requests.push(response) + STDOUT.puts response.to_json + end + end + end +end -- cgit v1.2.1 From a92693df7742214a44caa521f9be7ab52f99d6b6 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 23 Oct 2017 15:57:06 +0300 Subject: add InspectRequests helper --- lib/gitlab/testing/request_inspector_middleware.rb | 5 ++--- spec/features/projects/environments/environment_spec.rb | 9 +++++++-- spec/support/inspect_requests.rb | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 spec/support/inspect_requests.rb diff --git a/lib/gitlab/testing/request_inspector_middleware.rb b/lib/gitlab/testing/request_inspector_middleware.rb index 0ca21bd6a37..ff5bf9d74f4 100644 --- a/lib/gitlab/testing/request_inspector_middleware.rb +++ b/lib/gitlab/testing/request_inspector_middleware.rb @@ -30,12 +30,12 @@ module Gitlab request_headers = env_http_headers(env) status, headers, body = @app.call(env) - log_response({ + log_response(OpenStruct.new( url: url, status_code: status, request_headers: request_headers, response_headers: headers - }) + )) [status, headers, body] end @@ -52,7 +52,6 @@ module Gitlab def log_response(response) @@logged_requests.push(response) - STDOUT.puts response.to_json end end end diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index c9f12e877b3..e0fc60e45ae 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' feature 'Environment' do + include InspectRequests + given(:project) { create(:project) } given(:user) { create(:user) } given(:role) { :developer } @@ -193,11 +195,14 @@ feature 'Environment' do create(:environment, project: project, name: 'staging-1.0/review', state: :available) - - visit folder_project_environments_path(project, id: 'staging-1.0') end it 'renders a correct environment folder' do + reqs = inspect_requests do + visit folder_project_environments_path(project, id: 'staging-1.0') + end + + expect(reqs.first.status_code).to eq(200) expect(page).to have_content('Environments / staging-1.0') end end diff --git a/spec/support/inspect_requests.rb b/spec/support/inspect_requests.rb new file mode 100644 index 00000000000..5947700c1ea --- /dev/null +++ b/spec/support/inspect_requests.rb @@ -0,0 +1,15 @@ +require_relative './wait_for_requests' + +module InspectRequests + extend self + include WaitForRequests + + def inspect_requests + Gitlab::Testing::RequestInspectorMiddleware.log_requests! + yield + block_and_wait_for_requests_complete + Gitlab::Testing::RequestInspectorMiddleware.requests + ensure + Gitlab::Testing::RequestInspectorMiddleware.stop_logging! + end +end -- cgit v1.2.1 From 1ad8a42eff6df2b3caa7e2e704f9e61935d905e1 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Mon, 23 Oct 2017 17:37:58 +0300 Subject: remove unnecessary :js option in download_spec --- spec/features/projects/artifacts/download_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/artifacts/download_spec.rb b/spec/features/projects/artifacts/download_spec.rb index f1bdb2812c6..6f76c14910b 100644 --- a/spec/features/projects/artifacts/download_spec.rb +++ b/spec/features/projects/artifacts/download_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Download artifact', :js do +feature 'Download artifact' do let(:project) { create(:project, :public) } let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) } let(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) } -- cgit v1.2.1 From 57a275791ff0e263dbe07ba7f1bfc4fdf53842cf Mon Sep 17 00:00:00 2001 From: Brett Walker Date: Mon, 23 Oct 2017 19:04:57 +0300 Subject: grab the correct username when confirming secondary email --- app/controllers/confirmations_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index 80ab681ed87..43b5d557429 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -15,7 +15,8 @@ class ConfirmationsController < Devise::ConfirmationsController if signed_in?(:user) after_sign_in(resource) else - Gitlab::AppLogger.info("Email Confirmed: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip}") + username = (_resource_name == :email ? resource.user.username : resource.username) + Gitlab::AppLogger.info("Email Confirmed: username=#{username} email=#{resource.email} ip=#{request.remote_ip}") flash[:notice] += " Please sign in." new_session_path(:user) end -- cgit v1.2.1 From bb943537adbeaec64b6b9a703ffb17dfa1af5fd5 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Tue, 24 Oct 2017 07:16:57 +0300 Subject: Update i18n in FE docs, marking, interpolation --- changelogs/unreleased/update-fe-i18n-guide.yml | 5 ++++ doc/development/fe_guide/index.md | 4 +++ doc/development/i18n/externalization.md | 40 +++++++++++++++++++------- 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/update-fe-i18n-guide.yml diff --git a/changelogs/unreleased/update-fe-i18n-guide.yml b/changelogs/unreleased/update-fe-i18n-guide.yml new file mode 100644 index 00000000000..10bcf7836c6 --- /dev/null +++ b/changelogs/unreleased/update-fe-i18n-guide.yml @@ -0,0 +1,5 @@ +--- +title: Update i18n section in FE docs for marking and interpolation +merge_request: +author: +type: changed diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md index 73366eb9f3f..8f956681693 100644 --- a/doc/development/fe_guide/index.md +++ b/doc/development/fe_guide/index.md @@ -106,6 +106,10 @@ Frontend security practices. ## [Accessibility](accessibility.md) Our accessibility standards and resources. +## [Internationalization (i18n) and Translations](../i18n/externalization.md) +Frontend internationalization support is described in [this document](../i18n/). +The [externalization part of the guide](../i18n/externalization.md) explains the helpers/methods available. + [rails]: http://rubyonrails.org/ [haml]: http://haml.info/ diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md index 167260b6e0e..7c38260406d 100644 --- a/doc/development/i18n/externalization.md +++ b/doc/development/i18n/externalization.md @@ -180,15 +180,43 @@ aren't in the message with id `1 pipeline`. ## Working with special content + +### Just marking content for parsing + +- In Ruby/HAML: + + ```ruby + _('Subscribe') + ``` + +- In JavaScript: + + ```js + import { __ } from '../../../locale'; + const label = __('Subscribe'); + ``` + + +Sometimes there are some dynamic translations that can't be found by the +parser when running `bundle exec rake gettext:find`. For these scenarios you can +use the [`_N` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind). + +There is also and alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a). + ### Interpolation - In Ruby/HAML: ```ruby - _("Hello %{name}") % { name: 'Joe' } + _("Hello %{name}") % { name: 'Joe' } => 'Hello Joe' ``` -- In JavaScript: Not supported at this moment. +- In JavaScript: + + ```js + import { __, sprintf } from '../../../locale'; + sprintf(__('Hello %{username}'), { username: 'Joe' }) => 'Hello Joe' + ``` ### Plurals @@ -234,14 +262,6 @@ Sometimes you need to add some context to the text that you want to translate s__('OpenedNDaysAgo|Opened') ``` -### Just marking content for parsing - -Sometimes there are some dynamic translations that can't be found by the -parser when running `bundle exec rake gettext:find`. For these scenarios you can -use the [`_N` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind). - -There is also and alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a). - ## Adding a new language Let's suppose you want to add translations for a new language, let's say French. -- cgit v1.2.1 From 196df264467c2332fbeed1ff350ef176e92d0fd6 Mon Sep 17 00:00:00 2001 From: Brett Walker Date: Tue, 24 Oct 2017 09:23:35 +0300 Subject: fix to pass static-analysis --- app/controllers/confirmations_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb index 43b5d557429..8ca01a6e2c6 100644 --- a/app/controllers/confirmations_controller.rb +++ b/app/controllers/confirmations_controller.rb @@ -10,12 +10,12 @@ class ConfirmationsController < Devise::ConfirmationsController users_almost_there_path end - def after_confirmation_path_for(_resource_name, resource) + def after_confirmation_path_for(resource_name, resource) # incoming resource can either be a :user or an :email if signed_in?(:user) after_sign_in(resource) else - username = (_resource_name == :email ? resource.user.username : resource.username) + username = (resource_name == :email ? resource.user.username : resource.username) Gitlab::AppLogger.info("Email Confirmed: username=#{username} email=#{resource.email} ip=#{request.remote_ip}") flash[:notice] += " Please sign in." new_session_path(:user) -- cgit v1.2.1 From 6d0045d2671c11854ee1e34609f28526470f5ee2 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 10:47:03 +0300 Subject: fix rubocop violations --- lib/gitlab/testing/request_inspector_middleware.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/gitlab/testing/request_inspector_middleware.rb b/lib/gitlab/testing/request_inspector_middleware.rb index ff5bf9d74f4..a5ac800c735 100644 --- a/lib/gitlab/testing/request_inspector_middleware.rb +++ b/lib/gitlab/testing/request_inspector_middleware.rb @@ -1,3 +1,5 @@ +# rubocop:disable Style/ClassVars + module Gitlab module Testing class RequestInspectorMiddleware @@ -30,12 +32,13 @@ module Gitlab request_headers = env_http_headers(env) status, headers, body = @app.call(env) - log_response(OpenStruct.new( + request = OpenStruct.new( url: url, status_code: status, request_headers: request_headers, response_headers: headers - )) + ) + log_request request [status, headers, body] end @@ -43,14 +46,14 @@ module Gitlab private def env_http_headers(env) - Hash[*env.select {|k,v| k.start_with? 'HTTP_'} - .collect {|k,v| [k.sub(/^HTTP_/, ''), v]} - .collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]} + Hash[*env.select {|k, v| k.start_with? 'HTTP_'} + .collect {|k, v| [k.sub(/^HTTP_/, ''), v]} + .collect {|k, v| [k.split('_').collect(&:capitalize).join('-'), v]} .sort .flatten] end - def log_response(response) + def log_request(response) @@logged_requests.push(response) end end -- cgit v1.2.1 From b2273415bfa251e4d7604a7dc5677996bda80725 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 14:00:46 +0300 Subject: fix race condition when loading labels in filter bar --- spec/features/issues/filtered_search/dropdown_label_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index cbc4f8d4c50..40a59f834ba 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -68,7 +68,7 @@ describe 'Dropdown label', :js do it 'shows loading indicator when opened and hides it when loaded' do filtered_search.set('label:') - expect(find(js_dropdown_label)).to have_css('.filter-dropdown-loading') + expect(page).to have_css("#{js_dropdown_label} .filter-dropdown-loading", visible: true) expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading') end -- cgit v1.2.1 From 80c25e8b9ab4ed3a8e38c40e0b257476df61ed75 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 14:32:42 +0300 Subject: fix string escaping within latex example --- spec/features/projects/wiki/user_creates_wiki_page_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index e72b7dc0dd5..4a9d1cb87e1 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -77,14 +77,14 @@ describe 'User creates wiki page' do [stem] ++++ - \sqrt{4} = 2 + \\sqrt{4} = 2 ++++ another part [latexmath] ++++ - \beta_x \gamma + \\beta_x \\gamma ++++ stem:[2+2] is 4 -- cgit v1.2.1 From 01605bc78c57e3c6e1fbdb5d2397e1ebf78d7b2b Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 15:29:37 +0300 Subject: fix body scrollTop references --- spec/features/merge_requests/diff_notes_resolve_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 7264b3b6517..a1a6792d677 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -192,7 +192,7 @@ feature 'Diff notes resolve', :js do page.find('.discussion-next-btn').click end - expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 + expect(page.evaluate_script("window.pageYOffset")).to be > 0 end it 'hides jump to next button when all resolved' do @@ -308,7 +308,7 @@ feature 'Diff notes resolve', :js do page.find('.discussion-next-btn').click end - expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 + expect(page.evaluate_script("window.pageYOffset")).to be > 0 end it 'updates updated text after resolving note' do -- cgit v1.2.1 From 5d9377275b3a5fe054ff29e2644d80846ec7ba58 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 15:53:33 +0300 Subject: fix issue in which enter key from fill_in command was intercepted by autocomplete code --- spec/features/issues/user_uses_slash_commands_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index 9f5e25ff2cb..c4c06ed514b 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -226,7 +226,7 @@ feature 'Issues > User uses quick actions', :js do end it 'applies the commands to both issues and moves the issue' do - write_note("/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"\n/move #{target_project.full_path}") + write_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}") expect(page).to have_content 'Commands applied' expect(issue.reload).to be_closed @@ -245,7 +245,7 @@ feature 'Issues > User uses quick actions', :js do end it 'moves the issue and applies the commands to both issues' do - write_note("/move #{target_project.full_path}\n/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"") + write_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"") expect(page).to have_content 'Commands applied' expect(issue.reload).to be_closed -- cgit v1.2.1 From 9e538fd0129a08ba1b45ce3babfdf7a20198137f Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 16:01:11 +0300 Subject: remove unneeded accept header --- spec/features/merge_requests/diffs_spec.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index 21bbf82be77..d56149173a1 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -7,10 +7,6 @@ feature 'Diffs URL', :js do let(:merge_request) { create(:merge_request, source_project: project) } context 'when visit with */* as accept header' do - before do - page.driver.add_header('Accept', '*/*') - end - it 'renders the notes' do create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master' -- cgit v1.2.1 From f44665c893a1d54dd7f69d559e404b285e25b611 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 16:25:04 +0300 Subject: slow down requests for dropzone uploads to avoid race conditions --- lib/gitlab/testing/request_blocker_middleware.rb | 12 ++++++++++++ spec/features/uploads/user_uploads_file_to_note_spec.rb | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/gitlab/testing/request_blocker_middleware.rb b/lib/gitlab/testing/request_blocker_middleware.rb index aa67fa08577..4a8e3c2eee0 100644 --- a/lib/gitlab/testing/request_blocker_middleware.rb +++ b/lib/gitlab/testing/request_blocker_middleware.rb @@ -7,6 +7,7 @@ module Gitlab class RequestBlockerMiddleware @@num_active_requests = Concurrent::AtomicFixnum.new(0) @@block_requests = Concurrent::AtomicBoolean.new(false) + @@slow_requests = Concurrent::AtomicBoolean.new(false) # Returns the number of requests the server is currently processing. def self.num_active_requests @@ -19,9 +20,15 @@ module Gitlab @@block_requests.value = true end + # Slows down incoming requests (useful for race conditions). + def self.slow_requests! + @@slow_requests.value = true + end + # Allows the server to accept requests again. def self.allow_requests! @@block_requests.value = false + @@slow_requests.value = false end def initialize(app) @@ -33,6 +40,7 @@ module Gitlab if block_requests? block_request(env) else + sleep 0.2 if slow_requests? @app.call(env) end ensure @@ -45,6 +53,10 @@ module Gitlab @@block_requests.true? end + def slow_requests? + @@slow_requests.true? + end + def block_request(env) [503, {}, []] end diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb index 1261ffdc2ee..47b89d262f3 100644 --- a/spec/features/uploads/user_uploads_file_to_note_spec.rb +++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb @@ -21,6 +21,14 @@ feature 'User uploads file to note' do end context 'uploading is in progress' do + before do + Gitlab::Testing::RequestBlockerMiddleware.slow_requests! + end + + after do + Gitlab::Testing::RequestBlockerMiddleware.allow_requests! + end + it 'shows "Cancel" button on uploading', :js do dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) -- cgit v1.2.1 From 72717b591d8b2cb963ceb8266015e1b80a036ac0 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 16:52:33 +0300 Subject: correct the issues list count for label:none filter --- spec/features/issues/filtered_search/filter_issues_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 2974016c6a7..b3c50964810 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -139,7 +139,7 @@ describe 'Filter issues', :js do input_filtered_search('label:none') expect_tokens([label_token('none', false)]) - expect_issues_list_count(8) + expect_issues_list_count(4) expect_filtered_search_input_empty end -- cgit v1.2.1 From 34f7e825635ed8ce963a4b587ae37a6e7c0696e3 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 16:59:29 +0300 Subject: add accept_confirm around "delete comment" button --- spec/features/snippets/notes_on_personal_snippets_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index d089fb5b730..269351e55c9 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -110,7 +110,7 @@ describe 'Comments on personal snippets', :js do open_more_actions_dropdown(snippet_notes[0]) page.within("#notes-list li#note_#{snippet_notes[0].id}") do - click_on 'Delete comment' + accept_confirm { click_on 'Delete comment' } end wait_for_requests -- cgit v1.2.1 From 03fbdde7cd6fbd07027a14b676ca580f831ed015 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 17:55:30 +0300 Subject: add accept_confirm around "delete tag" button --- spec/features/tags/master_deletes_tag_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb index f5b3774122b..dfda664d673 100644 --- a/spec/features/tags/master_deletes_tag_spec.rb +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -64,7 +64,7 @@ feature 'Master deletes tag' do def delete_first_tag page.within('.content') do - first('.btn-remove').click + accept_confirm { first('.btn-remove').click } end end end -- cgit v1.2.1 From c09e5004e5f35b34c03c8d14a8f8b7b38af687c3 Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 18:03:18 +0300 Subject: add accept_confirm around "remove" button --- spec/features/projects/members/groups_with_access_list_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb index b1053982eee..a51c09102e1 100644 --- a/spec/features/projects/members/groups_with_access_list_spec.rb +++ b/spec/features/projects/members/groups_with_access_list_spec.rb @@ -40,7 +40,7 @@ feature 'Projects > Members > Groups with access list', :js do scenario 'deletes group link' do page.within(first('.group_member')) do - find('.btn-remove').click + accept_confirm { find('.btn-remove').click } end wait_for_requests -- cgit v1.2.1 From ecc5160aa9680783241571a67658b23f4f121ccc Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 18:10:48 +0300 Subject: fix member expire calendar selection by triggering blur --- spec/features/projects/members/groups_with_access_list_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb index a51c09102e1..7f067aadec6 100644 --- a/spec/features/projects/members/groups_with_access_list_spec.rb +++ b/spec/features/projects/members/groups_with_access_list_spec.rb @@ -31,6 +31,7 @@ feature 'Projects > Members > Groups with access list', :js do tomorrow = Date.today + 3 fill_in "member_expires_at_#{group.id}", with: tomorrow.strftime("%F") + find('body').click wait_for_requests page.within(find('li.group_member')) do -- cgit v1.2.1 From ff5b9115ddae3e281d0626707011ed9ebae5b02c Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Tue, 24 Oct 2017 18:21:09 +0300 Subject: add accept_confirm around "destroy/revoke" buttons --- spec/features/profiles/oauth_applications_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index 8cb240077eb..d1edeef8da4 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -14,7 +14,7 @@ describe 'Profile > Applications' do page.within('.oauth-applications') do expect(page).to have_content('Your applications (1)') - click_button 'Destroy' + accept_confirm { click_button 'Destroy' } end expect(page).to have_content('The application was deleted successfully') @@ -28,7 +28,7 @@ describe 'Profile > Applications' do page.within('.oauth-authorized-applications') do expect(page).to have_content('Authorized applications (1)') - click_button 'Revoke' + accept_confirm { click_button 'Revoke' } end expect(page).to have_content('The application was revoked access.') -- cgit v1.2.1 From 0bfb2aff7c2d74428321b42a25f8b7e92b8407e0 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 24 Oct 2017 17:41:19 +0100 Subject: Fixed user profile tab being off-screen --- app/assets/stylesheets/framework/blocks.scss | 9 ++++++++- changelogs/unreleased/fix-user-tab-activity-mobile.yml | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/fix-user-tab-activity-mobile.yml diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index dbd990f84c1..8819a0c20f4 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -209,7 +209,6 @@ padding: 24px 0 0; .nav-links { - justify-content: center; width: 100%; float: none; @@ -217,6 +216,14 @@ float: none; } } + + li:first-child { + margin-left: auto; + } + + li:last-child { + margin-right: auto; + } } .group-info { diff --git a/changelogs/unreleased/fix-user-tab-activity-mobile.yml b/changelogs/unreleased/fix-user-tab-activity-mobile.yml new file mode 100644 index 00000000000..a7e4fcb4355 --- /dev/null +++ b/changelogs/unreleased/fix-user-tab-activity-mobile.yml @@ -0,0 +1,5 @@ +--- +title: Fixed user profile activity tab being off-screen on mobile +merge_request: +author: +type: fixed -- cgit v1.2.1 From b5079721bfff6fd36d79da9c6ab22bfd9009f752 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Tue, 24 Oct 2017 22:48:55 +0100 Subject: Add spec for root diff discussion note --- spec/javascripts/notes_spec.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 2514f7ea841..8514c7ac5a1 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -362,13 +362,33 @@ import '~/notes'; $form.closest.and.returnValues(row, $form); $form.find.and.returnValues(discussionContainer); body.attr.and.returnValue(''); - - Notes.prototype.renderDiscussionNote.call(notes, note, $form); }); it('should call Notes.animateAppendNote', () => { + Notes.prototype.renderDiscussionNote.call(notes, note, $form); + expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list')); }); + + it('should append to row selected with line_code', () => { + $form.length = 0; + note.discussion_line_code = 'line_code'; + note.diff_discussion_html = ''; + + const line = document.createElement('div'); + line.id = note.discussion_line_code; + document.body.appendChild(line); + + $form.closest.and.returnValues($form); + spyOn(document, 'getElementById').and.callThrough(); + spyOn($.fn, 'after').and.callThrough(); + + Notes.prototype.renderDiscussionNote.call(notes, note, $form); + + expect(document.getElementById).toHaveBeenCalledWith(note.discussion_line_code); + expect($.fn.after).toHaveBeenCalled(); + expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html); + }); }); describe('Discussion sub note', () => { -- cgit v1.2.1 From e6b0f4420059285e1ad6e98d98321381ebd9d671 Mon Sep 17 00:00:00 2001 From: "Luke \"Jared\" Bennett" Date: Tue, 24 Oct 2017 23:01:49 +0100 Subject: Split project and group milestone dispatcher branch --- app/assets/javascripts/dispatcher.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 07535508d59..98b843279aa 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -229,6 +229,10 @@ import DueDateSelectors from './due_date_select'; case 'projects:milestones:new': case 'projects:milestones:edit': case 'projects:milestones:update': + new ZenMode(); + new DueDateSelectors(); + new GLForm($('.milestone-form'), true); + break; case 'groups:milestones:new': case 'groups:milestones:edit': case 'groups:milestones:update': -- cgit v1.2.1 From 4598c00a8f565a33c4460ae920ce7a65ba6540cc Mon Sep 17 00:00:00 2001 From: Richard Clamp Date: Wed, 25 Oct 2017 06:50:26 +0300 Subject: Add spec for QA::Scenario::Entrypoint For added confidence, and because I plan to fiddle with some behaviours shortly, add spec testing to the newly extracted QA::Scenario::Entrypoint class. --- qa/spec/scenario/entrypoint_spec.rb | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 qa/spec/scenario/entrypoint_spec.rb diff --git a/qa/spec/scenario/entrypoint_spec.rb b/qa/spec/scenario/entrypoint_spec.rb new file mode 100644 index 00000000000..3fd068b641c --- /dev/null +++ b/qa/spec/scenario/entrypoint_spec.rb @@ -0,0 +1,46 @@ +describe QA::Scenario::Entrypoint do + subject do + Class.new(QA::Scenario::Entrypoint) do + tags :rspec + end + end + + context '#perform' do + let(:config) { spy('Specs::Config') } + let(:release) { spy('Runtime::Release') } + let(:runner) { spy('Specs::Runner') } + + before do + allow(config).to receive(:perform) { |&block| block.call config } + allow(runner).to receive(:perform) { |&block| block.call runner } + + stub_const('QA::Specs::Config', config) + stub_const('QA::Runtime::Release', release) + stub_const('QA::Specs::Runner', runner) + end + + it 'should set address' do + subject.perform("hello") + + expect(config).to have_received(:address=).with("hello") + end + + context 'no paths' do + it 'should call runner with default arguments' do + subject.perform("test") + + expect(runner).to have_received(:rspec) + .with(hash_including(files: 'qa/specs/features')) + end + end + + context 'specifying paths' do + it 'should call runner with paths' do + subject.perform('test', 'path1', 'path2') + + expect(runner).to have_received(:rspec) + .with(hash_including(files: %w(path1 path2))) + end + end + end +end -- cgit v1.2.1 From 05728e785ce7cd39c4c517aa0ea50b3bba44d537 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 26 Oct 2017 11:14:31 +0100 Subject: [WIP] Move multi-file editor store to Vuex --- app/assets/javascripts/api.js | 1 + .../repo/components/new_branch_form.vue | 49 +++--- app/assets/javascripts/repo/components/repo.vue | 78 +++------- .../repo/components/repo_commit_section.vue | 167 ++++++++------------- .../repo/components/repo_edit_button.vue | 75 ++++----- .../javascripts/repo/components/repo_editor.vue | 147 +++++++----------- .../javascripts/repo/components/repo_file.vue | 19 +-- .../repo/components/repo_file_buttons.vue | 45 ++---- .../repo/components/repo_loading_file.vue | 10 +- .../repo/components/repo_prev_directory.vue | 28 ++-- .../javascripts/repo/components/repo_preview.vue | 33 ++-- .../javascripts/repo/components/repo_sidebar.vue | 116 +++----------- .../javascripts/repo/components/repo_tab.vue | 24 ++- .../javascripts/repo/components/repo_tabs.vue | 12 +- .../repo/helpers/monaco_loader_helper.js | 4 - app/assets/javascripts/repo/index.js | 82 +++++----- app/assets/javascripts/repo/mixins/repo_mixin.js | 17 --- app/assets/javascripts/repo/services/index.js | 28 ++++ app/assets/javascripts/repo/stores/actions.js | 94 ++++++++++++ .../javascripts/repo/stores/actions/branch.js | 20 +++ app/assets/javascripts/repo/stores/actions/file.js | 50 ++++++ app/assets/javascripts/repo/stores/actions/tree.js | 70 +++++++++ app/assets/javascripts/repo/stores/getters.js | 39 +++++ app/assets/javascripts/repo/stores/index.js | 15 ++ .../javascripts/repo/stores/mutation_types.js | 26 ++++ app/assets/javascripts/repo/stores/mutations.js | 54 +++++++ .../javascripts/repo/stores/mutations/branch.js | 9 ++ .../javascripts/repo/stores/mutations/file.js | 50 ++++++ .../javascripts/repo/stores/mutations/tree.js | 27 ++++ app/assets/javascripts/repo/stores/repo_store.js | 7 - app/assets/javascripts/repo/stores/state.js | 21 +++ app/assets/javascripts/repo/stores/utils.js | 73 +++++++++ app/views/shared/repo/_repo.html.haml | 4 +- 33 files changed, 910 insertions(+), 584 deletions(-) delete mode 100644 app/assets/javascripts/repo/mixins/repo_mixin.js create mode 100644 app/assets/javascripts/repo/services/index.js create mode 100644 app/assets/javascripts/repo/stores/actions.js create mode 100644 app/assets/javascripts/repo/stores/actions/branch.js create mode 100644 app/assets/javascripts/repo/stores/actions/file.js create mode 100644 app/assets/javascripts/repo/stores/actions/tree.js create mode 100644 app/assets/javascripts/repo/stores/getters.js create mode 100644 app/assets/javascripts/repo/stores/index.js create mode 100644 app/assets/javascripts/repo/stores/mutation_types.js create mode 100644 app/assets/javascripts/repo/stores/mutations.js create mode 100644 app/assets/javascripts/repo/stores/mutations/branch.js create mode 100644 app/assets/javascripts/repo/stores/mutations/file.js create mode 100644 app/assets/javascripts/repo/stores/mutations/tree.js create mode 100644 app/assets/javascripts/repo/stores/state.js create mode 100644 app/assets/javascripts/repo/stores/utils.js diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 242b3e2b990..d963101028a 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -16,6 +16,7 @@ const Api = { usersPath: '/api/:version/users.json', commitPath: '/api/:version/projects/:id/repository/commits', branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch', + createBranchPath: '/api/:version/projects/:id/repository/branches', group(groupId, callback) { const url = Api.buildUrl(Api.groupPath) diff --git a/app/assets/javascripts/repo/components/new_branch_form.vue b/app/assets/javascripts/repo/components/new_branch_form.vue index eac43e692b0..ba7090e4a9d 100644 --- a/app/assets/javascripts/repo/components/new_branch_form.vue +++ b/app/assets/javascripts/repo/components/new_branch_form.vue @@ -1,18 +1,12 @@ diff --git a/app/assets/javascripts/repo/components/repo.vue b/app/assets/javascripts/repo/components/repo.vue index 788976a9804..0bc5271f95c 100644 --- a/app/assets/javascripts/repo/components/repo.vue +++ b/app/assets/javascripts/repo/components/repo.vue @@ -1,75 +1,42 @@ @@ -88,15 +55,6 @@ export default { - - + diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue index 0d6259a37a8..37fc35f35c9 100644 --- a/app/assets/javascripts/repo/components/repo_commit_section.vue +++ b/app/assets/javascripts/repo/components/repo_commit_section.vue @@ -1,141 +1,97 @@