diff options
Diffstat (limited to 'spec/features/projects/jobs_spec.rb')
-rw-r--r-- | spec/features/projects/jobs_spec.rb | 260 |
1 files changed, 220 insertions, 40 deletions
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 83293c0ca7d..2076ce7b4f7 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -5,7 +5,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do let(:user) { create(:user) } let(:user_access_level) { :developer } let(:project) { create(:project, :repository) } - let(:pipeline) { create(:ci_pipeline, project: project) } + let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) } let(:job) { create(:ci_build, :trace_live, pipeline: pipeline) } let(:job2) { create(:ci_build) } @@ -20,7 +20,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end describe "GET /:project/jobs" do - let!(:job) { create(:ci_build, pipeline: pipeline) } + let!(:job) { create(:ci_build, pipeline: pipeline) } context "Pending scope" do before do @@ -115,36 +115,44 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do context "Job from project" do let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline) } - before do + it 'shows status name', :js do visit project_job_path(project, job) - end - it 'shows status name', :js do + wait_for_requests + expect(page).to have_css('.ci-status.ci-success', text: 'passed') end - it 'shows commit`s data' do - expect(page.status_code).to eq(200) + it 'shows commit`s data', :js do + requests = inspect_requests() do + visit project_job_path(project, job) + end + + wait_for_requests + expect(requests.first.status_code).to eq(200) expect(page).to have_content pipeline.sha[0..7] - expect(page).to have_content pipeline.git_commit_message - expect(page).to have_content pipeline.git_author_name + expect(page).to have_content pipeline.commit.title end - it 'shows active job' do + it 'shows active job', :js do + visit project_job_path(project, job) + + wait_for_requests expect(page).to have_selector('.build-job.active') end end - context 'sidebar' do + context 'sidebar', :js do let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline, name: '<img src=x onerror=alert(document.domain)>') } before do visit project_job_path(project, job) + wait_for_requests end it 'renders escaped tooltip name' do page.within('aside.right-sidebar') do - expect(find('.active.build-job a')['data-title']).to eq('<img src="x"> - passed') + expect(find('.active.build-job a')['data-original-title']).to eq('<img src=x onerror=alert(document.domain)> - passed') end end end @@ -199,7 +207,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do it { expect(page.status_code).to eq(404) } end - context "Download artifacts" do + context "Download artifacts", :js do before do job.update(legacy_artifacts_file: artifacts_file) visit project_job_path(project, job) @@ -208,9 +216,22 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do it 'has button to download artifacts' do expect(page).to have_content 'Download' end + + it 'downloads the zip file when user clicks the download button' do + requests = inspect_requests() do + click_link 'Download' + end + + artifact_request = requests.find { |req| req.url.match(%r{artifacts/download}) } + + expect(artifact_request.response_headers["Content-Disposition"]).to eq(%Q{attachment; filename="#{job.artifacts_file.filename}"}) + expect(artifact_request.response_headers['Content-Transfer-Encoding']).to eq("binary") + expect(artifact_request.response_headers['Content-Type']).to eq("image/gif") + expect(artifact_request.body).to eq(job.artifacts_file.file.read.b) + end end - context 'Artifacts expire date' do + context 'Artifacts expire date', :js do before do job.update(legacy_artifacts_file: artifacts_file, artifacts_expire_at: expire_at) @@ -231,12 +252,12 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do context 'when user has ability to update job' do it 'keeps artifacts when keep button is clicked' do - expect(page).to have_content 'The artifacts will be removed' + expect(page).to have_content 'The artifacts will be removed in' click_link 'Keep' expect(page).to have_no_link 'Keep' - expect(page).to have_no_content 'The artifacts will be removed' + expect(page).to have_no_content 'The artifacts will be removed in' end end @@ -314,6 +335,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do shared_examples 'expected variables behavior' do it 'shows variable key and value after click', :js do + expect(page).to have_content('Token') expect(page).to have_css('.js-reveal-variables') expect(page).not_to have_css('.js-build-variable') expect(page).not_to have_css('.js-build-value') @@ -347,39 +369,167 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'when job starts environment' do - let(:environment) { create(:environment, project: project) } - let(:pipeline) { create(:ci_pipeline, project: project) } + context 'when job starts environment', :js do + let(:environment) { create(:environment, name: 'production', project: project) } - context 'job is successfull and has deployment' do - let(:deployment) { create(:deployment) } - let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, deployments: [deployment], pipeline: pipeline) } + context 'job is successful and has deployment' do + let(:build) { create(:ci_build, :success, :trace_live, environment: environment.name, pipeline: pipeline) } + let!(:deployment) { create(:deployment, environment: environment, project: environment.project, deployable: build) } - it 'shows a link for the job' do - visit project_job_path(project, job) + before do + visit project_job_path(project, build) + wait_for_requests + # scroll to the top of the page first + execute_script "window.scrollTo(0,0)" + end + it 'shows a link for the job' do expect(page).to have_link environment.name end + + it 'shows deployment message' do + expect(page).to have_content 'This job is the most recent deployment' + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + end end context 'job is complete and not successful' do - let(:job) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) } + let(:build) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) } it 'shows a link for the job' do - visit project_job_path(project, job) + visit project_job_path(project, build) + wait_for_requests + # scroll to the top of the page first + execute_script "window.scrollTo(0,0)" expect(page).to have_link environment.name + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") end end - context 'job creates a new deployment' do - let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) } - let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, pipeline: pipeline) } + context 'deployment still not finished' do + let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) } it 'shows a link to latest deployment' do - visit project_job_path(project, job) + visit project_job_path(project, build) + wait_for_all_requests + # scroll to the top of the page first + execute_script "window.scrollTo(0,0)" + + expect(page).to have_link environment.name + expect(page).to have_content 'This job is creating a deployment' + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + end + end + end + + describe 'environment info in job view', :js do + before do + visit project_job_path(project, job) + wait_for_requests + # scroll to the top of the page first + execute_script "window.scrollTo(0,0)" + end + + context 'job with outdated deployment' do + let(:job) { create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline) } + let(:second_build) { create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline) } + let(:environment) { create(:environment, name: 'staging', project: project) } + let!(:first_deployment) { create(:deployment, environment: environment, deployable: job) } + let!(:second_deployment) { create(:deployment, environment: environment, deployable: second_build) } + + it 'shows deployment message' do + expected_text = 'This job is an out-of-date deployment ' \ + "to staging. View the most recent deployment ##{second_deployment.iid}." + + expect(page).to have_css('.environment-information', text: expected_text) + end + + it 'renders a link to the most recent deployment' do + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + expect(find('.js-job-deployment-link')['href']).to include(second_deployment.deployable.project.path, second_deployment.deployable_id.to_s) + end + end + + context 'job failed to deploy' do + let(:job) { create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline) } + let!(:environment) { create(:environment, name: 'staging', project: project) } + + it 'shows deployment message' do + expected_text = 'The deployment of this job to staging did not succeed.' + + expect(page).to have_css( + '.environment-information', text: expected_text) + end + end + + context 'job will deploy' do + let(:job) { create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline) } + + context 'when environment exists' do + let!(:environment) { create(:environment, name: 'staging', project: project) } + + it 'shows deployment message' do + expected_text = 'This job is creating a deployment to staging' + + expect(page).to have_css( + '.environment-information', text: expected_text) + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + end + + context 'when it has deployment' do + let!(:deployment) { create(:deployment, environment: environment) } + + it 'shows that deployment will be overwritten' do + expected_text = 'This job is creating a deployment to staging' + + expect(page).to have_css( + '.environment-information', text: expected_text) + expect(page).to have_css( + '.environment-information', text: 'latest deployment') + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + end + end + end + + context 'when environment does not exist' do + let!(:environment) { create(:environment, name: 'staging', project: project) } + + it 'shows deployment message' do + expected_text = 'This job is creating a deployment to staging' + + expect(page).to have_css( + '.environment-information', text: expected_text) + expect(page).not_to have_css( + '.environment-information', text: 'latest deployment') + expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") + end + end + end + + context 'job that failed to deploy and environment has not been created' do + let(:job) { create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline) } + let!(:environment) { create(:environment, name: 'staging', project: project) } + + it 'shows deployment message' do + expected_text = 'The deployment of this job to staging did not succeed' + + expect(page).to have_css( + '.environment-information', text: expected_text) + end + end - expect(page).to have_link('latest deployment') + context 'job that will deploy and environment has not been created' do + let(:job) { create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline) } + let!(:environment) { create(:environment, name: 'staging', project: project) } + + it 'shows deployment message' do + expected_text = 'This job is creating a deployment to staging' + + expect(page).to have_css( + '.environment-information', text: expected_text) + expect(page).not_to have_css( + '.environment-information', text: 'latest deployment') end end end @@ -392,7 +542,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do visit project_job_path(project, job) end - it 'shows manual action empty state' do + it 'shows manual action empty state', :js do expect(page).to have_content(job.detailed_status(user).illustration[:title]) expect(page).to have_content('This job requires a manual action') expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments') @@ -409,6 +559,30 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end + context 'Delayed job' do + let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) } + + before do + project.add_developer(user) + visit project_job_path(project, job) + end + + it 'shows delayed job', :js do + expect(page).to have_content('This is a scheduled to run in') + expect(page).to have_content("This job will automatically run after it's timer finishes.") + expect(page).to have_link('Unschedule job') + end + + it 'unschedules delayed job and shows manual action', :js do + click_link 'Unschedule job' + + wait_for_requests + expect(page).to have_content('This job requires a manual action') + expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments') + expect(page).to have_link('Trigger this manual action') + end + end + context 'Non triggered job' do let(:job) { create(:ci_build, :created, pipeline: pipeline) } @@ -416,14 +590,14 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do visit project_job_path(project, job) end - it 'shows empty state' do + it 'shows empty state', :js do expect(page).to have_content(job.detailed_status(user).illustration[:title]) expect(page).to have_content('This job has not been triggered yet') expect(page).to have_content('This job depends on upstream jobs that need to succeed in order for this job to be triggered') end end - context 'Pending job' do + context 'Pending job', :js do let(:job) { create(:ci_build, :pending, pipeline: pipeline) } before do @@ -450,7 +624,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'without log' do + context 'without log', :js do let(:job) { create(:ci_build, :canceled, pipeline: pipeline) } before do @@ -465,7 +639,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'Skipped job' do + context 'Skipped job', :js do let(:job) { create(:ci_build, :skipped, pipeline: pipeline) } before do @@ -479,7 +653,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'when job is failed but has no trace' do + context 'when job is failed but has no trace', :js do let(:job) { create(:ci_build, :failed, pipeline: pipeline) } it 'renders empty state' do @@ -542,20 +716,26 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - describe "GET /:project/jobs/:id/download" do + describe "GET /:project/jobs/:id/download", :js do before do job.update(legacy_artifacts_file: artifacts_file) visit project_job_path(project, job) + click_link 'Download' end context "Build from other project" do before do job2.update(legacy_artifacts_file: artifacts_file) - visit download_project_job_artifacts_path(project, job2) end - it { expect(page.status_code).to eq(404) } + it do + requests = inspect_requests() do + visit download_project_job_artifacts_path(project, job2) + end + + expect(requests.first.status_code).to eq(404) + end end end |