pipelines_spec.rb 16.1 KB
Newer Older
K
Kamil Trzcinski 已提交
1 2
require 'spec_helper'

3
describe 'Pipelines', :js do
4
  let(:project) { create(:project) }
K
Kamil Trzcinski 已提交
5

6 7
  context 'when user is logged in' do
    let(:user) { create(:user) }
8

9
    before do
10
      sign_in(user)
11
      project.team << [user, :developer]
12 13
    end

14
    describe 'GET /:project/pipelines' do
15
      let(:project) { create(:project, :repository) }
16 17 18 19 20 21 22

      let!(:pipeline) do
        create(
          :ci_empty_pipeline,
          project: project,
          ref: 'master',
          status: 'running',
23
          sha: project.commit.id
24
        )
25 26
      end

27 28 29 30 31 32 33
      context 'scope' do
        before do
          create(:ci_empty_pipeline, status: 'pending', project: project, sha: project.commit.id, ref: 'master')
          create(:ci_empty_pipeline, status: 'running', project: project, sha: project.commit.id, ref: 'master')
          create(:ci_empty_pipeline, status: 'created', project: project, sha: project.commit.id, ref: 'master')
          create(:ci_empty_pipeline, status: 'success', project: project, sha: project.commit.id, ref: 'master')
        end
34

35 36 37 38 39 40 41 42 43
        [:all, :running, :pending, :finished, :branches].each do |scope|
          context "when displaying #{scope}" do
            before do
              visit_project_pipelines(scope: scope)
            end

            it 'contains pipeline commit short SHA' do
              expect(page).to have_content(pipeline.short_sha)
            end
44

45 46 47
            it 'contains branch name' do
              expect(page).to have_content(pipeline.ref)
            end
48
          end
49
        end
R
Regis 已提交
50
      end
K
Kamil Trzcinski 已提交
51

52 53
      context 'header tabs' do
        before do
54
          visit project_pipelines_path(project)
55
          wait_for_requests
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
        end

        it 'shows a tab for All pipelines and count' do
          expect(page.find('.js-pipelines-tab-all a').text).to include('All')
          expect(page.find('.js-pipelines-tab-all .badge').text).to include('1')
        end

        it 'shows a tab for Pending pipelines and count' do
          expect(page.find('.js-pipelines-tab-pending a').text).to include('Pending')
          expect(page.find('.js-pipelines-tab-pending .badge').text).to include('0')
        end

        it 'shows a tab for Running pipelines and count' do
          expect(page.find('.js-pipelines-tab-running a').text).to include('Running')
          expect(page.find('.js-pipelines-tab-running .badge').text).to include('1')
        end

        it 'shows a tab for Finished pipelines and count' do
          expect(page.find('.js-pipelines-tab-finished a').text).to include('Finished')
          expect(page.find('.js-pipelines-tab-finished .badge').text).to include('0')
        end

        it 'shows a tab for Branches' do
          expect(page.find('.js-pipelines-tab-branches a').text).to include('Branches')
        end

        it 'shows a tab for Tags' do
          expect(page.find('.js-pipelines-tab-tags a').text).to include('Tags')
        end
      end

87 88 89 90 91 92
      context 'when pipeline is cancelable' do
        let!(:build) do
          create(:ci_build, pipeline: pipeline,
                            stage: 'test',
                            commands: 'test')
        end
K
Kamil Trzcinski 已提交
93

94 95 96 97
        before do
          build.run
          visit_project_pipelines
        end
K
Kamil Trzcinski 已提交
98

99
        it 'indicates that pipeline can be canceled' do
100
          expect(page).to have_selector('.js-pipelines-cancel-button')
101 102
          expect(page).to have_selector('.ci-running')
        end
103

104
        context 'when canceling' do
105
          before do
106
            accept_confirm { find('.js-pipelines-cancel-button').click }
107
            wait_for_requests
108
          end
109

110
          it 'indicated that pipelines was canceled' do
111
            expect(page).not_to have_selector('.js-pipelines-cancel-button')
112 113
            expect(page).to have_selector('.ci-canceled')
          end
114
        end
115
      end
116

117 118 119 120 121 122
      context 'when pipeline is retryable' do
        let!(:build) do
          create(:ci_build, pipeline: pipeline,
                            stage: 'test',
                            commands: 'test')
        end
R
Regis 已提交
123

124
        before do
125 126
          build.drop
          visit_project_pipelines
127
        end
128

129
        it 'indicates that pipeline can be retried' do
130
          expect(page).to have_selector('.js-pipelines-retry-button')
131 132
          expect(page).to have_selector('.ci-failed')
        end
133 134

        context 'when retrying' do
135 136
          before do
            find('.js-pipelines-retry-button').click
137
            wait_for_requests
138
          end
139

140
          it 'shows running pipeline that is not retryable' do
141
            expect(page).not_to have_selector('.js-pipelines-retry-button')
142 143
            expect(page).to have_selector('.ci-running')
          end
144
        end
145 146
      end

147 148 149 150 151
      context 'when pipeline has configuration errors' do
        let(:pipeline) do
          create(:ci_pipeline, :invalid, project: project)
        end

152 153 154
        before do
          visit_project_pipelines
        end
155

156
        it 'contains badge that indicates errors' do
157 158 159 160 161 162 163 164
          expect(page).to have_content 'yaml invalid'
        end

        it 'contains badge with tooltip which contains error' do
          expect(pipeline).to have_yaml_errors
          expect(page).to have_selector(
            %Q{span[data-original-title="#{pipeline.yaml_errors}"]})
        end
165 166 167 168 169 170 171 172 173 174

        it 'contains badge that indicates failure reason' do
          expect(page).to have_content 'error'
        end

        it 'contains badge with tooltip which contains failure reason' do
          expect(pipeline.failure_reason?).to eq true
          expect(page).to have_selector(
            %Q{span[data-original-title="#{pipeline.present.failure_reason}"]})
        end
175 176
      end

177 178 179
      context 'with manual actions' do
        let!(:manual) do
          create(:ci_build, :manual,
R
Regis 已提交
180
            pipeline: pipeline,
181 182 183
            name: 'manual build',
            stage: 'test',
            commands: 'test')
R
Regis 已提交
184
        end
185

186 187 188
        before do
          visit_project_pipelines
        end
189

190
        it 'has a dropdown with play button' do
191
          expect(page).to have_selector('.dropdown-new.btn.btn-default .icon-play')
192 193
        end

194 195 196
        it 'has link to the manual action' do
          find('.js-pipeline-dropdown-manual-actions').click

197
          expect(page).to have_button('manual build')
198
        end
199

200 201 202
        context 'when manual action was played' do
          before do
            find('.js-pipeline-dropdown-manual-actions').click
203
            click_button('manual build')
204
          end
205

206
          it 'enqueues manual action job' do
207
            expect(page).to have_selector('.js-pipeline-dropdown-manual-actions:disabled')
208
          end
209
        end
210 211
      end

212 213 214 215 216 217
      context 'for generic statuses' do
        context 'when running' do
          let!(:running) do
            create(:generic_commit_status,
              status: 'running',
              pipeline: pipeline,
218
              stage: 'test')
219
          end
220

221 222 223
          before do
            visit_project_pipelines
          end
224 225

          it 'is cancelable' do
226
            expect(page).to have_selector('.js-pipelines-cancel-button')
227
          end
228

229 230 231 232 233
          it 'has pipeline running' do
            expect(page).to have_selector('.ci-running')
          end

          context 'when canceling' do
234
            before do
235
              accept_alert { find('.js-pipelines-cancel-button').click }
236
            end
237

238
            it 'indicates that pipeline was canceled' do
239
              expect(page).not_to have_selector('.js-pipelines-cancel-button')
240 241
              expect(page).to have_selector('.ci-canceled')
            end
242
          end
243 244
        end

245 246 247 248 249 250 251 252 253 254 255 256 257
        context 'when failed' do
          let!(:status) do
            create(:generic_commit_status, :pending,
              pipeline: pipeline,
              stage: 'test')
          end

          before do
            status.drop
            visit_project_pipelines
          end

          it 'is not retryable' do
258
            expect(page).not_to have_selector('.js-pipelines-retry-button')
259 260 261 262 263
          end

          it 'has failed pipeline' do
            expect(page).to have_selector('.ci-failed')
          end
264 265 266
        end
      end

267 268 269 270 271 272 273 274 275
      context 'downloadable pipelines' do
        context 'with artifacts' do
          let!(:with_artifacts) do
            create(:ci_build, :artifacts, :success,
              pipeline: pipeline,
              name: 'rspec tests',
              stage: 'test')
          end

276 277 278
          before do
            visit_project_pipelines
          end
279 280 281 282 283 284 285 286 287 288

          it 'has artifats' do
            expect(page).to have_selector('.build-artifacts')
          end

          it 'has artifacts download dropdown' do
            find('.js-pipeline-dropdown-download').click

            expect(page).to have_link(with_artifacts.name)
          end
289 290 291 292 293 294 295 296

          it 'has download attribute on download links' do
            find('.js-pipeline-dropdown-download').click
            expect(page).to have_selector('a', text: 'Download')
            page.all('.build-artifacts a', text: 'Download').each do |link|
              expect(link[:download]).to eq ''
            end
          end
R
Regis 已提交
297
        end
K
Kamil Trzcinski 已提交
298

299 300 301 302 303 304 305
        context 'with artifacts expired' do
          let!(:with_artifacts_expired) do
            create(:ci_build, :artifacts_expired, :success,
              pipeline: pipeline,
              name: 'rspec',
              stage: 'test')
          end
306

307 308 309
          before do
            visit_project_pipelines
          end
310 311

          it { expect(page).not_to have_selector('.build-artifacts') }
312 313
        end

314 315 316 317 318 319 320 321
        context 'without artifacts' do
          let!(:without_artifacts) do
            create(:ci_build, :success,
              pipeline: pipeline,
              name: 'rspec',
              stage: 'test')
          end

322 323 324
          before do
            visit_project_pipelines
          end
325

326
          it { expect(page).not_to have_selector('.build-artifacts') }
327
        end
K
Kamil Trzcinski 已提交
328
      end
K
Kamil Trzcinski 已提交
329

330
      context 'mini pipeline graph' do
331
        let!(:build) do
332 333 334
          create(:ci_build, :pending, pipeline: pipeline,
                                      stage: 'build',
                                      name: 'build')
R
Regis 已提交
335
        end
336

337 338 339
        before do
          visit_project_pipelines
        end
340

341 342 343 344 345
        it 'should render a mini pipeline graph' do
          expect(page).to have_selector('.js-mini-pipeline-graph')
          expect(page).to have_selector('.js-builds-dropdown-button')
        end

346
        context 'when clicking a stage badge' do
347
          it 'should open a dropdown' do
348
            find('.js-builds-dropdown-button').click
349

350 351
            expect(page).to have_link build.name
          end
K
Kamil Trzcinski 已提交
352

353
          it 'should be possible to cancel pending build' do
354 355
            find('.js-builds-dropdown-button').click
            find('a.js-ci-action-icon').click
356

357 358
            expect(page).to have_content('canceled')
            expect(build.reload).to be_canceled
359 360
          end
        end
361 362 363

        context 'dropdown jobs list' do
          it 'should keep the dropdown open when the user ctr/cmd + clicks in the job name' do
364
            find('.js-builds-dropdown-button').click
365 366
            dropdown_item = find('.mini-pipeline-graph-dropdown-item').native

367
            %i(alt control).each do |meta_key|
368
              page.driver.browser.action
369
                .key_down(meta_key)
370
                .click(dropdown_item)
371
                .key_up(meta_key)
372 373
                .perform
            end
374 375 376 377

            expect(page).to have_selector('.js-ci-action-icon')
          end
        end
K
Kamil Trzcinski 已提交
378
      end
379 380 381

      context 'with pagination' do
        before do
382 383
          allow(Ci::Pipeline).to receive(:default_per_page).and_return(1)
          create(:ci_empty_pipeline,  project: project)
384 385 386
        end

        it 'should render pagination' do
387
          visit project_pipelines_path(project)
388
          wait_for_requests
389

390
          expect(page).to have_selector('.gl-pagination')
391 392
        end

393
        it 'should render second page of pipelines' do
394
          visit project_pipelines_path(project, page: '2')
395
          wait_for_requests
396

397
          expect(page).to have_selector('.gl-pagination .page', count: 2)
398 399
        end
      end
K
Kamil Trzcinski 已提交
400
    end
401

402
    describe 'GET /:project/pipelines/show' do
403
      let(:project) { create(:project, :repository) }
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422

      let(:pipeline) do
        create(:ci_empty_pipeline,
              project: project,
              sha: project.commit.id,
              user: user)
      end

      before do
        create_build('build', 0, 'build', :success)
        create_build('test', 1, 'rspec 0:2', :pending)
        create_build('test', 1, 'rspec 1:2', :running)
        create_build('test', 1, 'spinach 0:2', :created)
        create_build('test', 1, 'spinach 1:2', :created)
        create_build('test', 1, 'audit', :created)
        create_build('deploy', 2, 'production', :created)

        create(:generic_commit_status, pipeline: pipeline, stage: 'external', name: 'jenkins', stage_idx: 3)

423
        visit project_pipeline_path(project, pipeline)
424
        wait_for_requests
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
      end

      it 'shows a graph with grouped stages' do
        expect(page).to have_css('.js-pipeline-graph')

        # header
        expect(page).to have_text("##{pipeline.id}")
        expect(page).to have_selector(%Q(img[alt$="#{pipeline.user.name}'s avatar"]))
        expect(page).to have_link(pipeline.user.name, href: user_path(pipeline.user))

        # stages
        expect(page).to have_text('Build')
        expect(page).to have_text('Test')
        expect(page).to have_text('Deploy')
        expect(page).to have_text('External')

        # builds
        expect(page).to have_text('rspec')
        expect(page).to have_text('spinach')
Z
Z.J. van de Weg 已提交
444
        expect(page).to have_text('rspec')
445 446 447 448 449 450 451 452 453
        expect(page).to have_text('production')
        expect(page).to have_text('jenkins')
      end

      def create_build(stage, stage_idx, name, status)
        create(:ci_build, pipeline: pipeline, stage: stage, stage_idx: stage_idx, name: name, status: status)
      end
    end

454
    describe 'POST /:project/pipelines' do
455
      let(:project) { create(:project, :repository) }
456 457

      before do
458
        visit new_project_pipeline_path(project)
459 460
      end

461
      context 'for valid commit', :js do
462 463 464 465 466 467 468
        before do
          click_button project.default_branch

          page.within '.dropdown-menu' do
            click_link 'master'
          end
        end
469

470
        context 'with gitlab-ci.yml' do
471 472 473
          before do
            stub_ci_pipeline_to_return_yaml_file
          end
474

475 476 477
          it 'creates a new pipeline' do
            expect { click_on 'Create pipeline' }
              .to change { Ci::Pipeline.count }.by(1)
478 479

            expect(Ci::Pipeline.last).to be_web
480
          end
481 482
        end

483
        context 'without gitlab-ci.yml' do
484 485 486
          before do
            click_on 'Create pipeline'
          end
487

488
          it { expect(page).to have_content('Missing .gitlab-ci.yml file') }
489 490
        end
      end
R
Regis 已提交
491
    end
K
Kamil Trzcinski 已提交
492

493
    describe 'Create pipelines' do
494
      let(:project) { create(:project, :repository) }
495

496
      before do
497
        visit new_project_pipeline_path(project)
498
      end
499

500 501
      describe 'new pipeline page' do
        it 'has field to add a new pipeline' do
502 503
          expect(page).to have_selector('.js-branch-select')
          expect(find('.js-branch-select')).to have_content project.default_branch
504
          expect(page).to have_content('Create for')
R
Regis 已提交
505
        end
K
Kamil Trzcinski 已提交
506
      end
K
Kamil Trzcinski 已提交
507

508
      describe 'find pipelines' do
509
        it 'shows filtered pipelines', :js do
510
          click_button project.default_branch
511

512 513 514 515 516 517
          page.within '.dropdown-menu' do
            find('.dropdown-input-field').native.send_keys('fix')

            page.within '.dropdown-content' do
              expect(page).to have_content('fix')
            end
518 519
          end
        end
K
Kamil Trzcinski 已提交
520 521
      end
    end
K
Kamil Trzcinski 已提交
522
  end
U
ubudzisz 已提交
523

524
  context 'when user is not logged in' do
U
ubudzisz 已提交
525
    before do
526
      visit project_pipelines_path(project)
U
ubudzisz 已提交
527 528
    end

529
    context 'when project is public' do
530
      let(:project) { create(:project, :public, :repository) }
531

532
      it { expect(page).to have_content 'Build with confidence' }
U
ubudzisz 已提交
533 534
    end

535
    context 'when project is private' do
536
      let(:project) { create(:project, :private, :repository) }
U
ubudzisz 已提交
537

538
      it { expect(page).to have_content 'You need to sign in' }
U
ubudzisz 已提交
539 540
    end
  end
541 542

  def visit_project_pipelines(**query)
543
    visit project_pipelines_path(project, query)
544
    wait_for_requests
545
  end
K
Kamil Trzcinski 已提交
546
end