Replace the project/builds/artifacts.feature
spinach test with an rspec analog
This commit is contained in:
parent
f9fcd2b410
commit
d550211eb1
8 changed files with 159 additions and 344 deletions
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: 'Replace the `project/builds/artifacts.feature` spinach test with an rspec analog'
|
||||
merge_request: 18729
|
||||
author: '@blackst0ne'
|
||||
type: other
|
|
@ -1,65 +0,0 @@
|
|||
Feature: Project Builds Artifacts
|
||||
Background:
|
||||
Given I sign in as a user
|
||||
And I own a project
|
||||
And project has CI enabled
|
||||
And project has a recent build
|
||||
|
||||
Scenario: I download build artifacts
|
||||
Given recent build has artifacts available
|
||||
When I visit recent build details page
|
||||
And I click artifacts download button
|
||||
Then download of build artifacts archive starts
|
||||
|
||||
Scenario: I browse build artifacts
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
Then I should see content of artifacts archive
|
||||
And I should see the build header
|
||||
|
||||
Scenario: I browse subdirectory of build artifacts
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
And I click link to subdirectory within build artifacts
|
||||
Then I should see content of subdirectory within artifacts archive
|
||||
And I should see the directory name in the breadcrumb
|
||||
|
||||
Scenario: I browse directory with UTF-8 characters in name
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
And recent build artifacts contain directory with UTF-8 characters
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
And I navigate to directory with UTF-8 characters in name
|
||||
Then I should see content of directory with UTF-8 characters in name
|
||||
|
||||
Scenario: I try to browse directory with invalid UTF-8 characters in name
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
And recent build artifacts contain directory with invalid UTF-8 characters
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
And I navigate to parent directory of directory with invalid name
|
||||
Then I should not see directory with invalid name on the list
|
||||
|
||||
@javascript
|
||||
Scenario: I download a single file from build artifacts
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
And I click a link to file within build artifacts
|
||||
Then I see a download link
|
||||
|
||||
@javascript
|
||||
Scenario: I click on a row in an artifacts table
|
||||
Given recent build has artifacts available
|
||||
And recent build has artifacts metadata available
|
||||
When I visit recent build details page
|
||||
And I click artifacts browse button
|
||||
And I click a first row within build artifacts table
|
||||
Then page with a coresponding path is loading
|
|
@ -1,98 +0,0 @@
|
|||
class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps
|
||||
include SharedAuthentication
|
||||
include SharedProject
|
||||
include SharedBuilds
|
||||
include RepoHelpers
|
||||
include WaitForRequests
|
||||
|
||||
step 'I click artifacts download button' do
|
||||
click_link 'Download'
|
||||
end
|
||||
|
||||
step 'I click artifacts browse button' do
|
||||
click_link 'Browse'
|
||||
expect(page).not_to have_selector('.build-sidebar')
|
||||
end
|
||||
|
||||
step 'I should see content of artifacts archive' do
|
||||
page.within('.tree-table') do
|
||||
expect(page).to have_no_content '..'
|
||||
expect(page).to have_content 'other_artifacts_0.1.2'
|
||||
expect(page).to have_content 'ci_artifacts.txt'
|
||||
expect(page).to have_content 'rails_sample.jpg'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see the build header' do
|
||||
page.within('.build-header') do
|
||||
expect(page).to have_content "Job ##{@build.id} in pipeline ##{@pipeline.id} for #{@pipeline.short_sha}"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I click link to subdirectory within build artifacts' do
|
||||
page.within('.tree-table') { click_link 'other_artifacts_0.1.2' }
|
||||
end
|
||||
|
||||
step 'I should see content of subdirectory within artifacts archive' do
|
||||
page.within('.tree-table') do
|
||||
expect(page).to have_content '..'
|
||||
expect(page).to have_content 'another-subdirectory'
|
||||
expect(page).to have_content 'doc_sample.txt'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see the directory name in the breadcrumb' do
|
||||
page.within('.repo-breadcrumb') do
|
||||
expect(page).to have_content 'other_artifacts_0.1.2'
|
||||
end
|
||||
end
|
||||
|
||||
step 'recent build artifacts contain directory with UTF-8 characters' do
|
||||
# metadata fixture contains relevant directory
|
||||
end
|
||||
|
||||
step 'I navigate to directory with UTF-8 characters in name' do
|
||||
page.within('.tree-table') { click_link 'tests_encoding' }
|
||||
page.within('.tree-table') { click_link 'utf8 test dir ✓' }
|
||||
end
|
||||
|
||||
step 'I should see content of directory with UTF-8 characters in name' do
|
||||
page.within('.tree-table') do
|
||||
expect(page).to have_content '..'
|
||||
expect(page).to have_content 'regular_file_2'
|
||||
end
|
||||
end
|
||||
|
||||
step 'recent build artifacts contain directory with invalid UTF-8 characters' do
|
||||
# metadata fixture contains relevant directory
|
||||
end
|
||||
|
||||
step 'I navigate to parent directory of directory with invalid name' do
|
||||
page.within('.tree-table') { click_link 'tests_encoding' }
|
||||
end
|
||||
|
||||
step 'I should not see directory with invalid name on the list' do
|
||||
page.within('.tree-table') do
|
||||
expect(page).to have_no_content('non-utf8-dir')
|
||||
end
|
||||
end
|
||||
|
||||
step 'I click a link to file within build artifacts' do
|
||||
page.within('.tree-table') { find_link('ci_artifacts.txt').click }
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
step 'I see a download link' do
|
||||
expect(page).to have_link 'download it'
|
||||
end
|
||||
|
||||
step 'I click a first row within build artifacts table' do
|
||||
row = first('tr[data-link]')
|
||||
@row_path = row['data-link']
|
||||
row.click
|
||||
end
|
||||
|
||||
step 'page with a coresponding path is loading' do
|
||||
expect(current_path).to eq @row_path
|
||||
end
|
||||
end
|
|
@ -1,53 +0,0 @@
|
|||
module SharedBuilds
|
||||
include Spinach::DSL
|
||||
|
||||
step 'project has CI enabled' do
|
||||
@project.enable_ci
|
||||
end
|
||||
|
||||
step 'project has coverage enabled' do
|
||||
@project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/)
|
||||
end
|
||||
|
||||
step 'project has a recent build' do
|
||||
@pipeline = create(:ci_empty_pipeline, project: @project, sha: @project.commit.sha, ref: 'master')
|
||||
@build = create(:ci_build, :running, :coverage, :trace_artifact, pipeline: @pipeline)
|
||||
end
|
||||
|
||||
step 'recent build is successful' do
|
||||
@build.success
|
||||
end
|
||||
|
||||
step 'recent build failed' do
|
||||
@build.drop
|
||||
end
|
||||
|
||||
step 'project has another build that is running' do
|
||||
create(:ci_build, pipeline: @pipeline, name: 'second build', status_event: 'run')
|
||||
end
|
||||
|
||||
step 'I visit recent build details page' do
|
||||
visit project_job_path(@project, @build)
|
||||
end
|
||||
|
||||
step 'recent build has artifacts available' do
|
||||
artifacts = Rails.root + 'spec/fixtures/ci_build_artifacts.zip'
|
||||
archive = fixture_file_upload(artifacts, 'application/zip')
|
||||
@build.update_attributes(legacy_artifacts_file: archive)
|
||||
end
|
||||
|
||||
step 'recent build has artifacts metadata available' do
|
||||
metadata = Rails.root + 'spec/fixtures/ci_build_artifacts_metadata.gz'
|
||||
gzip = fixture_file_upload(metadata, 'application/x-gzip')
|
||||
@build.update_attributes(legacy_artifacts_metadata: gzip)
|
||||
end
|
||||
|
||||
step 'recent build has a build trace' do
|
||||
@build.trace.set('job trace')
|
||||
end
|
||||
|
||||
step 'download of build artifacts archive starts' do
|
||||
expect(page.response_headers['Content-Type']).to eq 'application/zip'
|
||||
expect(page.response_headers['Content-Transfer-Encoding']).to eq 'binary'
|
||||
end
|
||||
end
|
|
@ -1,67 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'Browse artifact', :js do
|
||||
let(:project) { create(:project, :public) }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
|
||||
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
|
||||
let(:browse_url) do
|
||||
browse_path('other_artifacts_0.1.2')
|
||||
end
|
||||
|
||||
def browse_path(path)
|
||||
browse_project_job_artifacts_path(project, job, path)
|
||||
end
|
||||
|
||||
context 'when visiting old URL' do
|
||||
before do
|
||||
visit browse_url.sub('/-/jobs', '/builds')
|
||||
end
|
||||
|
||||
it "redirects to new URL" do
|
||||
expect(page.current_path).to eq(browse_url)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when browsing a directory with an text file' do
|
||||
let(:txt_entry) { job.artifacts_metadata_entry('other_artifacts_0.1.2/doc_sample.txt') }
|
||||
|
||||
before do
|
||||
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
|
||||
allow(Gitlab.config.pages).to receive(:artifacts_server).and_return(true)
|
||||
end
|
||||
|
||||
context 'when the project is public' do
|
||||
it "shows external link icon and styles" do
|
||||
visit browse_url
|
||||
|
||||
link = first('.tree-item-file-external-link')
|
||||
|
||||
expect(page).to have_link('doc_sample.txt', href: file_project_job_artifacts_path(project, job, path: txt_entry.blob.path))
|
||||
expect(link[:target]).to eq('_blank')
|
||||
expect(link[:rel]).to include('noopener')
|
||||
expect(link[:rel]).to include('noreferrer')
|
||||
expect(page).to have_selector('.js-artifact-tree-external-icon')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the project is private' do
|
||||
let!(:private_project) { create(:project, :private) }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: private_project) }
|
||||
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
private_project.add_developer(user)
|
||||
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'shows internal link styles' do
|
||||
visit browse_project_job_artifacts_path(private_project, job, 'other_artifacts_0.1.2')
|
||||
|
||||
expect(page).to have_link('doc_sample.txt')
|
||||
expect(page).not_to have_selector('.js-artifact-tree-external-icon')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,61 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
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) }
|
||||
|
||||
shared_examples 'downloading' do
|
||||
it 'downloads the zip' do
|
||||
expect(page.response_headers['Content-Disposition'])
|
||||
.to eq(%Q{attachment; filename="#{job.artifacts_file.filename}"})
|
||||
|
||||
# Check the content does match, but don't print this as error message
|
||||
expect(page.source.b == job.artifacts_file.file.read.b)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when downloading' do
|
||||
before do
|
||||
visit download_url
|
||||
end
|
||||
|
||||
context 'via job id' do
|
||||
let(:download_url) do
|
||||
download_project_job_artifacts_path(project, job)
|
||||
end
|
||||
|
||||
it_behaves_like 'downloading'
|
||||
end
|
||||
|
||||
context 'via branch name and job name' do
|
||||
let(:download_url) do
|
||||
latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name)
|
||||
end
|
||||
|
||||
it_behaves_like 'downloading'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when visiting old URL' do
|
||||
before do
|
||||
visit download_url.sub('/-/jobs', '/builds')
|
||||
end
|
||||
|
||||
context 'via job id' do
|
||||
let(:download_url) do
|
||||
download_project_job_artifacts_path(project, job)
|
||||
end
|
||||
|
||||
it_behaves_like 'downloading'
|
||||
end
|
||||
|
||||
context 'via branch name and job name' do
|
||||
let(:download_url) do
|
||||
latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name)
|
||||
end
|
||||
|
||||
it_behaves_like 'downloading'
|
||||
end
|
||||
end
|
||||
end
|
110
spec/features/projects/artifacts/user_browses_artifacts_spec.rb
Normal file
110
spec/features/projects/artifacts/user_browses_artifacts_spec.rb
Normal file
|
@ -0,0 +1,110 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "User browses artifacts" do
|
||||
let(:project) { create(:project, :public) }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
|
||||
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
|
||||
let(:browse_url) { browse_project_job_artifacts_path(project, job, "other_artifacts_0.1.2") }
|
||||
|
||||
context "when visiting old URL" do
|
||||
it "redirects to new URL" do
|
||||
visit(browse_url.sub("/-/jobs", "/builds"))
|
||||
|
||||
expect(page.current_path).to eq(browse_url)
|
||||
end
|
||||
end
|
||||
|
||||
context "when browsing artifacts root directory" do
|
||||
before do
|
||||
visit(browse_project_job_artifacts_path(project, job))
|
||||
end
|
||||
|
||||
it "shows artifacts" do
|
||||
expect(page).not_to have_selector(".build-sidebar")
|
||||
|
||||
page.within(".tree-table") do
|
||||
expect(page).to have_no_content("..")
|
||||
.and have_content("other_artifacts_0.1.2")
|
||||
.and have_content("ci_artifacts.txt")
|
||||
.and have_content("rails_sample.jpg")
|
||||
end
|
||||
|
||||
page.within(".build-header") do
|
||||
expect(page).to have_content("Job ##{job.id} in pipeline ##{pipeline.id} for #{pipeline.short_sha}")
|
||||
end
|
||||
end
|
||||
|
||||
it "shows an artifact" do
|
||||
click_link("ci_artifacts.txt")
|
||||
|
||||
expect(page).to have_link("download it")
|
||||
end
|
||||
end
|
||||
|
||||
context "when browsing a directory with UTF-8 characters in its name" do
|
||||
before do
|
||||
visit(browse_project_job_artifacts_path(project, job))
|
||||
end
|
||||
|
||||
it "shows correct content", :js do
|
||||
page.within(".tree-table") do
|
||||
click_link("tests_encoding")
|
||||
|
||||
expect(page).to have_no_content("non-utf8-dir")
|
||||
|
||||
click_link("utf8 test dir ✓")
|
||||
|
||||
expect(page).to have_content("..").and have_content("regular_file_2")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when browsing a directory with a text file" do
|
||||
let(:txt_entry) { job.artifacts_metadata_entry("other_artifacts_0.1.2/doc_sample.txt") }
|
||||
|
||||
before do
|
||||
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
|
||||
allow(Gitlab.config.pages).to receive(:artifacts_server).and_return(true)
|
||||
end
|
||||
|
||||
context "when the project is public" do
|
||||
before do
|
||||
visit(browse_url)
|
||||
end
|
||||
|
||||
it "shows correct content" do
|
||||
link = first(".tree-item-file-external-link")
|
||||
|
||||
expect(link[:target]).to eq("_blank")
|
||||
expect(link[:rel]).to include("noopener").and include("noreferrer")
|
||||
expect(page).to have_link("doc_sample.txt", href: file_project_job_artifacts_path(project, job, path: txt_entry.blob.path))
|
||||
.and have_selector(".js-artifact-tree-external-icon")
|
||||
|
||||
page.within(".tree-table") do
|
||||
expect(page).to have_content("..").and have_content("another-subdirectory")
|
||||
end
|
||||
|
||||
page.within(".repo-breadcrumb") do
|
||||
expect(page).to have_content("other_artifacts_0.1.2")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the project is private" do
|
||||
let!(:private_project) { create(:project, :private) }
|
||||
let(:pipeline) { create(:ci_empty_pipeline, project: private_project) }
|
||||
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
private_project.add_developer(user)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
visit(browse_project_job_artifacts_path(private_project, job, "other_artifacts_0.1.2"))
|
||||
end
|
||||
|
||||
it { expect(page).to have_link("doc_sample.txt").and have_no_selector(".js-artifact-tree-external-icon") }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "User downloads artifacts" do
|
||||
set(:project) { create(:project, :public) }
|
||||
set(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) }
|
||||
set(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
|
||||
|
||||
shared_examples "downloading" do
|
||||
it "downloads the zip" do
|
||||
expect(page.response_headers["Content-Disposition"]).to eq(%Q{attachment; filename="#{job.artifacts_file.filename}"})
|
||||
expect(page.response_headers['Content-Transfer-Encoding']).to eq("binary")
|
||||
expect(page.response_headers['Content-Type']).to eq("application/zip")
|
||||
expect(page.source.b).to eq(job.artifacts_file.file.read.b)
|
||||
end
|
||||
end
|
||||
|
||||
context "when downloading" do
|
||||
before do
|
||||
visit(url)
|
||||
end
|
||||
|
||||
context "via job id" do
|
||||
set(:url) { download_project_job_artifacts_path(project, job) }
|
||||
|
||||
it_behaves_like "downloading"
|
||||
end
|
||||
|
||||
context "via branch name and job name" do
|
||||
set(:url) { latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name) }
|
||||
|
||||
it_behaves_like "downloading"
|
||||
end
|
||||
|
||||
context "via clicking the `Download` button" do
|
||||
set(:url) { project_job_path(project, job) }
|
||||
|
||||
before do
|
||||
click_link("Download")
|
||||
end
|
||||
|
||||
it_behaves_like "downloading"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue