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

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

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

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

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

      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 54
      context 'header tabs' do
        before do
          visit namespace_project_pipelines_path(project.namespace, 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 106
          before do
            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 165 166
          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
      end

167 168 169
      context 'with manual actions' do
        let!(:manual) do
          create(:ci_build, :manual,
R
Regis 已提交
170
            pipeline: pipeline,
171 172 173
            name: 'manual build',
            stage: 'test',
            commands: 'test')
R
Regis 已提交
174
        end
175

176 177 178
        before do
          visit_project_pipelines
        end
179

180
        it 'has a dropdown with play button' do
181
          expect(page).to have_selector('.dropdown-new.btn.btn-default .icon-play')
182 183
        end

184 185 186
        it 'has link to the manual action' do
          find('.js-pipeline-dropdown-manual-actions').click

187
          expect(page).to have_button('manual build')
188
        end
189

190 191 192
        context 'when manual action was played' do
          before do
            find('.js-pipeline-dropdown-manual-actions').click
193
            click_button('manual build')
194
          end
195

196
          it 'enqueues manual action job' do
197
            expect(page).to have_selector('.js-pipeline-dropdown-manual-actions:disabled')
198
          end
199
        end
200 201
      end

202 203 204 205 206 207
      context 'for generic statuses' do
        context 'when running' do
          let!(:running) do
            create(:generic_commit_status,
              status: 'running',
              pipeline: pipeline,
208
              stage: 'test')
209
          end
210

211 212 213
          before do
            visit_project_pipelines
          end
214 215

          it 'is cancelable' do
216
            expect(page).to have_selector('.js-pipelines-cancel-button')
217
          end
218

219 220 221 222 223
          it 'has pipeline running' do
            expect(page).to have_selector('.ci-running')
          end

          context 'when canceling' do
224 225 226
            before do
              find('.js-pipelines-cancel-button').trigger('click')
            end
227

228
            it 'indicates that pipeline was canceled' do
229
              expect(page).not_to have_selector('.js-pipelines-cancel-button')
230 231
              expect(page).to have_selector('.ci-canceled')
            end
232
          end
233 234
        end

235 236 237 238 239 240 241 242 243 244 245 246 247
        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
248
            expect(page).not_to have_selector('.js-pipelines-retry-button')
249 250 251 252 253
          end

          it 'has failed pipeline' do
            expect(page).to have_selector('.ci-failed')
          end
254 255 256
        end
      end

257 258 259 260 261 262 263 264 265
      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

266 267 268
          before do
            visit_project_pipelines
          end
269 270 271 272 273 274 275 276 277 278

          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
279 280 281 282 283 284 285 286

          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 已提交
287
        end
K
Kamil Trzcinski 已提交
288

289 290 291 292 293 294 295
        context 'with artifacts expired' do
          let!(:with_artifacts_expired) do
            create(:ci_build, :artifacts_expired, :success,
              pipeline: pipeline,
              name: 'rspec',
              stage: 'test')
          end
296

297 298 299
          before do
            visit_project_pipelines
          end
300 301

          it { expect(page).not_to have_selector('.build-artifacts') }
302 303
        end

304 305 306 307 308 309 310 311
        context 'without artifacts' do
          let!(:without_artifacts) do
            create(:ci_build, :success,
              pipeline: pipeline,
              name: 'rspec',
              stage: 'test')
          end

312 313 314
          before do
            visit_project_pipelines
          end
315

316
          it { expect(page).not_to have_selector('.build-artifacts') }
317
        end
K
Kamil Trzcinski 已提交
318
      end
K
Kamil Trzcinski 已提交
319

320
      context 'mini pipeline graph' do
321
        let!(:build) do
322 323 324
          create(:ci_build, :pending, pipeline: pipeline,
                                      stage: 'build',
                                      name: 'build')
R
Regis 已提交
325
        end
326

327 328 329
        before do
          visit_project_pipelines
        end
330

331 332 333 334 335
        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

336
        context 'when clicking a stage badge' do
337 338
          it 'should open a dropdown' do
            find('.js-builds-dropdown-button').trigger('click')
339

340 341
            expect(page).to have_link build.name
          end
K
Kamil Trzcinski 已提交
342

343
          it 'should be possible to cancel pending build' do
344
            find('.js-builds-dropdown-button').trigger('click')
345
            find('a.js-ci-action-icon').trigger('click')
346

347 348
            expect(page).to have_content('canceled')
            expect(build.reload).to be_canceled
349 350
          end
        end
351 352 353 354 355 356 357 358 359 360 361 362

        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')

            execute_script('var e = $.Event("keydown", { keyCode: 64 }); $("body").trigger(e);')

            find('.mini-pipeline-graph-dropdown-item').trigger('click')

            expect(page).to have_selector('.js-ci-action-icon')
          end
        end
K
Kamil Trzcinski 已提交
363
      end
364 365 366

      context 'with pagination' do
        before do
367 368
          allow(Ci::Pipeline).to receive(:default_per_page).and_return(1)
          create(:ci_empty_pipeline,  project: project)
369 370 371 372
        end

        it 'should render pagination' do
          visit namespace_project_pipelines_path(project.namespace, project)
373
          wait_for_requests
374

375
          expect(page).to have_selector('.gl-pagination')
376 377
        end

378
        it 'should render second page of pipelines' do
379
          visit namespace_project_pipelines_path(project.namespace, project, page: '2')
380
          wait_for_requests
381

382
          expect(page).to have_selector('.gl-pagination .page', count: 2)
383 384
        end
      end
K
Kamil Trzcinski 已提交
385
    end
386

387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
    describe 'GET /:project/pipelines/show' do
      let(:project) { create(:project) }

      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)

        visit namespace_project_pipeline_path(project.namespace, project, pipeline)
409
        wait_for_requests
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
      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 已提交
429
        expect(page).to have_text('rspec')
430 431 432 433 434 435 436 437 438
        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

439 440 441 442 443
    describe 'POST /:project/pipelines' do
      let(:project) { create(:project) }

      before do
        visit new_namespace_project_pipeline_path(project.namespace, project)
444 445
      end

446 447 448 449 450 451 452 453
      context 'for valid commit', js: true do
        before do
          click_button project.default_branch

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

455
        context 'with gitlab-ci.yml' do
456 457 458
          before do
            stub_ci_pipeline_to_return_yaml_file
          end
459

460 461 462
          it 'creates a new pipeline' do
            expect { click_on 'Create pipeline' }
              .to change { Ci::Pipeline.count }.by(1)
463 464

            expect(Ci::Pipeline.last).to be_web
465
          end
466 467
        end

468
        context 'without gitlab-ci.yml' do
469 470 471
          before do
            click_on 'Create pipeline'
          end
472

473
          it { expect(page).to have_content('Missing .gitlab-ci.yml file') }
474 475
        end
      end
R
Regis 已提交
476
    end
K
Kamil Trzcinski 已提交
477

478 479
    describe 'Create pipelines' do
      let(:project) { create(:project) }
480

481 482 483
      before do
        visit new_namespace_project_pipeline_path(project.namespace, project)
      end
484

485 486
      describe 'new pipeline page' do
        it 'has field to add a new pipeline' do
487 488
          expect(page).to have_selector('.js-branch-select')
          expect(find('.js-branch-select')).to have_content project.default_branch
489
          expect(page).to have_content('Create for')
R
Regis 已提交
490
        end
K
Kamil Trzcinski 已提交
491
      end
K
Kamil Trzcinski 已提交
492

493 494
      describe 'find pipelines' do
        it 'shows filtered pipelines', js: true do
495
          click_button project.default_branch
496

497 498 499 500 501 502
          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
503 504
          end
        end
K
Kamil Trzcinski 已提交
505 506
      end
    end
K
Kamil Trzcinski 已提交
507
  end
U
ubudzisz 已提交
508

509
  context 'when user is not logged in' do
U
ubudzisz 已提交
510
    before do
511
      visit namespace_project_pipelines_path(project.namespace, project)
U
ubudzisz 已提交
512 513
    end

514 515 516
    context 'when project is public' do
      let(:project) { create(:project, :public) }

517
      it { expect(page).to have_content 'Build with confidence' }
518
      it { expect(page).to have_http_status(:success) }
U
ubudzisz 已提交
519 520
    end

521 522
    context 'when project is private' do
      let(:project) { create(:project, :private) }
U
ubudzisz 已提交
523

524
      it { expect(page).to have_content 'You need to sign in' }
U
ubudzisz 已提交
525 526
    end
  end
527 528 529

  def visit_project_pipelines(**query)
    visit namespace_project_pipelines_path(project.namespace, project, query)
530
    wait_for_requests
531
  end
K
Kamil Trzcinski 已提交
532
end