Commit 12ff699d authored by Mark Lapierre's avatar Mark Lapierre

Merge branch 'qa-e2e-version-control-for-personal-snippets' into 'master'

E2E - Version control for snippets - Part 1

Closes #207110

See merge request gitlab-org/gitlab!28068
parents 19762b70 334bc111
...@@ -207,7 +207,7 @@ export default { ...@@ -207,7 +207,7 @@ export default {
category="primary" category="primary"
variant="success" variant="success"
:disabled="updatePrevented" :disabled="updatePrevented"
data-qa-selector="create_snippet_button" data-qa-selector="submit_button"
@click="handleFormSubmit" @click="handleFormSubmit"
>{{ saveButtonLabel }}</gl-button >{{ saveButtonLabel }}</gl-button
> >
......
...@@ -99,6 +99,7 @@ export default { ...@@ -99,6 +99,7 @@ export default {
class="mr-2" class="mr-2"
:ssh-link="snippet.sshUrlToRepo" :ssh-link="snippet.sshUrlToRepo"
:http-link="snippet.httpUrlToRepo" :http-link="snippet.httpUrlToRepo"
data-qa-selector="clone_button"
/> />
</template> </template>
</blob-header> </blob-header>
......
...@@ -207,6 +207,8 @@ export default { ...@@ -207,6 +207,8 @@ export default {
:category="action.category" :category="action.category"
:class="action.cssClass" :class="action.cssClass"
:href="action.href" :href="action.href"
data-qa-selector="snippet_action_button"
:data-qa-action="action.text"
@click="action.click ? action.click() : undefined" @click="action.click ? action.click() : undefined"
> >
{{ action.text }} {{ action.text }}
......
...@@ -57,6 +57,7 @@ export default { ...@@ -57,6 +57,7 @@ export default {
v-gl-tooltip.hover v-gl-tooltip.hover
:title="$options.copyURLTooltip" :title="$options.copyURLTooltip"
:data-clipboard-text="sshLink" :data-clipboard-text="sshLink"
data-qa-selector="copy_ssh_url_button"
icon="copy-to-clipboard" icon="copy-to-clipboard"
class="d-inline-flex" class="d-inline-flex"
/> />
...@@ -75,6 +76,7 @@ export default { ...@@ -75,6 +76,7 @@ export default {
v-gl-tooltip.hover v-gl-tooltip.hover
:title="$options.copyURLTooltip" :title="$options.copyURLTooltip"
:data-clipboard-text="httpLink" :data-clipboard-text="httpLink"
data-qa-selector="copy_http_url_button"
icon="copy-to-clipboard" icon="copy-to-clipboard"
class="d-inline-flex" class="d-inline-flex"
/> />
......
...@@ -44,9 +44,9 @@ ...@@ -44,9 +44,9 @@
.form-actions .form-actions
- if @snippet.new_record? - if @snippet.new_record?
= f.submit 'Create snippet', class: "btn-success btn qa-create-snippet-button" = f.submit 'Create snippet', class: "btn-success btn", data: { qa_selector: 'submit_button' }
- else - else
= f.submit 'Save changes', class: "btn-success btn" = f.submit 'Save changes', class: "btn-success btn", data: { qa_selector: 'submit_button' }
- if @snippet.project_id - if @snippet.project_id
= link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel" = link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel"
......
...@@ -191,6 +191,7 @@ module QA ...@@ -191,6 +191,7 @@ module QA
autoload :New, 'qa/page/dashboard/snippet/new' autoload :New, 'qa/page/dashboard/snippet/new'
autoload :Index, 'qa/page/dashboard/snippet/index' autoload :Index, 'qa/page/dashboard/snippet/index'
autoload :Show, 'qa/page/dashboard/snippet/show' autoload :Show, 'qa/page/dashboard/snippet/show'
autoload :Edit, 'qa/page/dashboard/snippet/edit'
end end
end end
......
...@@ -122,6 +122,14 @@ module QA ...@@ -122,6 +122,14 @@ module QA
run("git merge #{branch}") run("git merge #{branch}")
end end
def init_repository
run("git init")
end
def pull(repository = nil, branch = nil)
run(['git', 'pull', repository, branch].compact.join(' '))
end
def commits def commits
run('git log --oneline').to_s.split("\n") run('git log --oneline').to_s.split("\n")
end end
...@@ -177,6 +185,10 @@ module QA ...@@ -177,6 +185,10 @@ module QA
save_netrc_content save_netrc_content
end end
def file_content(file)
run("cat #{file}").to_s
end
private private
attr_reader :uri, :username, :password, :known_hosts_file, attr_reader :uri, :username, :password, :known_hosts_file,
......
...@@ -133,8 +133,13 @@ module QA ...@@ -133,8 +133,13 @@ module QA
end end
# replace with (..., page = self.class) # replace with (..., page = self.class)
def click_element(name, page = nil, text: nil, wait: Capybara.default_max_wait_time) def click_element(name, page = nil, **kwargs)
find_element(name, text: text, wait: wait).click wait_for_requests
wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
text = kwargs.delete(:text)
find(element_selector_css(name, kwargs), text: text, wait: wait).click
page.validate_elements_present! if page page.validate_elements_present! if page
end end
......
# frozen_string_literal: true
module QA
module Page
module Dashboard
module Snippet
class Edit < Page::Base
view 'app/views/shared/snippets/_form.html.haml' do
element :submit_button
end
view 'app/assets/javascripts/snippets/components/edit.vue' do
element :submit_button
end
def add_to_file_content(content)
finished_loading?
text_area.set content
text_area.has_text?(content) # wait for changes to take effect
end
def save_changes
click_element(:submit_button)
wait_until { assert_no_element(:submit_button) }
end
private
def text_area
find('#editor textarea', visible: false)
end
end
end
end
end
end
...@@ -6,7 +6,7 @@ module QA ...@@ -6,7 +6,7 @@ module QA
module Snippet module Snippet
class New < Page::Base class New < Page::Base
view 'app/assets/javascripts/snippets/components/edit.vue' do view 'app/assets/javascripts/snippets/components/edit.vue' do
element :create_snippet_button element :submit_button
end end
view 'app/assets/javascripts/snippets/components/snippet_description_edit.vue' do view 'app/assets/javascripts/snippets/components/snippet_description_edit.vue' do
...@@ -31,7 +31,7 @@ module QA ...@@ -31,7 +31,7 @@ module QA
element :description_placeholder element :description_placeholder
element :snippet_title element :snippet_title
element :snippet_file_name element :snippet_file_name
element :create_snippet_button element :submit_button
end end
view 'app/views/projects/_zen.html.haml' do view 'app/views/projects/_zen.html.haml' do
...@@ -63,8 +63,8 @@ module QA ...@@ -63,8 +63,8 @@ module QA
end end
def click_create_snippet_button def click_create_snippet_button
wait_until(reload: false) { !find_element(:create_snippet_button).disabled? } wait_until(reload: false) { !find_element(:submit_button).disabled? }
click_element :create_snippet_button click_element :submit_button
end end
private private
......
...@@ -35,6 +35,20 @@ module QA ...@@ -35,6 +35,20 @@ module QA
element :file_content element :file_content
end end
view 'app/assets/javascripts/snippets/components/snippet_header.vue' do
element :snippet_action_button
element :delete_snippet_button
end
view 'app/assets/javascripts/snippets/components/snippet_blob_view.vue' do
element :clone_button
end
view 'app/assets/javascripts/vue_shared/components/clone_dropdown.vue' do
element :copy_http_url_button
element :copy_ssh_url_button
end
def has_snippet_title?(snippet_title) def has_snippet_title?(snippet_title)
has_element? :snippet_title, text: snippet_title has_element? :snippet_title, text: snippet_title
end end
...@@ -61,6 +75,30 @@ module QA ...@@ -61,6 +75,30 @@ module QA
has_text?(file_content) has_text?(file_content)
end end
end end
def click_edit_button
finished_loading?
click_element(:snippet_action_button, action: 'Edit')
end
def click_delete_button
finished_loading?
click_element(:snippet_action_button, action: 'Delete')
click_element(:delete_snippet_button)
finished_loading? # wait for the page to reload after deletion
end
def get_repository_uri_http
finished_loading?
click_element(:clone_button)
Git::Location.new(find_element(:copy_http_url_button)['data-clipboard-text']).uri.to_s
end
def get_repository_uri_ssh
finished_loading?
click_element(:clone_button)
Git::Location.new(find_element(:copy_ssh_url_button)['data-clipboard-text']).uri.to_s
end
end end
end end
end end
......
# frozen_string_literal: true
module QA
context 'Create' do
describe 'Version control for personal snippets' do
let(:new_file) { 'new_snippet_file' }
let(:changed_content) { 'changes' }
let(:commit_message) { 'Changes to snippets' }
let(:added_content) { 'updated ' }
let(:branch_name) { 'master' }
let(:snippet) do
Resource::Snippet.fabricate! do |snippet|
snippet.file_name = new_file
end
end
let(:ssh_key) do
Resource::SSHKey.fabricate_via_api! do |resource|
resource.title = "my key title #{Time.now.to_f}"
end
end
let(:repository_uri_http) do
snippet
Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_http)
end
let(:repository_uri_ssh) do
ssh_key
snippet
Page::Dashboard::Snippet::Show.perform(&:get_repository_uri_ssh)
end
before do
Flow::Login.sign_in
end
it 'clones, pushes, and pulls a snippet over HTTP, edits via UI' do
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = repository_uri_http
push.file_name = new_file
push.file_content = changed_content
push.commit_message = commit_message
push.new_branch = false
end
page.refresh
verify_changes_in_ui
Page::Dashboard::Snippet::Show.perform(&:click_edit_button)
Page::Dashboard::Snippet::Edit.perform do |snippet|
snippet.add_to_file_content(added_content)
snippet.save_changes
end
Git::Repository.perform do |repository|
repository.init_repository
repository.pull(repository_uri_http, branch_name)
expect(repository.commits.size).to eq(3)
expect(repository.commits.first).to include('Update snippet')
expect(repository.file_content(new_file)).to include("#{added_content}#{changed_content}")
end
end
it 'clones, pushes, and pulls a snippet over SSH, deletes via UI' do
Resource::Repository::Push.fabricate! do |push|
push.repository_ssh_uri = repository_uri_ssh
push.ssh_key = ssh_key
push.file_name = new_file
push.file_content = changed_content
push.commit_message = commit_message
push.new_branch = false
end
page.refresh
verify_changes_in_ui
Page::Dashboard::Snippet::Show.perform(&:click_delete_button)
# attempt to pull a deleted snippet, get a missing repository error
Git::Repository.perform do |repository|
repository.uri = repository_uri_ssh
repository.use_ssh_key(ssh_key)
repository.init_repository
expect { repository.pull(repository_uri_ssh, branch_name) }
.to raise_error(QA::Git::Repository::RepositoryCommandError, /[fatal: Could not read from remote repository.]+/)
end
end
def verify_changes_in_ui
Page::Dashboard::Snippet::Show.perform do |snippet|
expect(snippet).to have_file_name(new_file)
expect(snippet).to have_file_content(changed_content)
end
end
end
end
end
...@@ -41,6 +41,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` ...@@ -41,6 +41,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
category="tertiary" category="tertiary"
class="d-inline-flex" class="d-inline-flex"
data-clipboard-text="ssh://foo.bar" data-clipboard-text="ssh://foo.bar"
data-qa-selector="copy_ssh_url_button"
icon="copy-to-clipboard" icon="copy-to-clipboard"
size="medium" size="medium"
title="Copy URL" title="Copy URL"
...@@ -81,6 +82,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` ...@@ -81,6 +82,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
category="tertiary" category="tertiary"
class="d-inline-flex" class="d-inline-flex"
data-clipboard-text="http://foo.bar" data-clipboard-text="http://foo.bar"
data-qa-selector="copy_http_url_button"
icon="copy-to-clipboard" icon="copy-to-clipboard"
size="medium" size="medium"
title="Copy URL" title="Copy URL"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment