github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/web/elm/tests/PipelineGridTests.elm (about) 1 module PipelineGridTests exposing (all) 2 3 import Application.Application as Application 4 import Common 5 import Concourse 6 import Data 7 import Expect 8 import Json.Encode as Encode 9 import Message.Callback as Callback 10 import Message.Effects exposing (Effect(..)) 11 import Message.Message exposing (DomID(..), Message(..), PipelinesSection(..)) 12 import Message.Subscription as Subscription exposing (Delivery(..)) 13 import Message.TopLevelMessage exposing (TopLevelMessage(..)) 14 import Set 15 import Test exposing (Test, describe, test) 16 import Test.Html.Event as Event 17 import Test.Html.Query as Query 18 import Test.Html.Selector exposing (class, containing, id, style, text) 19 import Url 20 21 22 all : Test 23 all = 24 let 25 viewportWithSize width height = 26 { scene = 27 { width = width 28 , height = height 29 } 30 , viewport = 31 { width = width 32 , height = height 33 , x = 0 34 , y = 0 35 } 36 } 37 38 findPipelineCard name = 39 Query.find [ class "pipeline-wrapper", containing [ text name ] ] 40 41 hasBounds { x, y, width, height } = 42 Query.has 43 [ style "position" "absolute" 44 , style "transform" 45 ("translate(" 46 ++ String.fromInt x 47 ++ "px," 48 ++ String.fromInt y 49 ++ "px)" 50 ) 51 , style "width" (String.fromInt width ++ "px") 52 , style "height" (String.fromInt height ++ "px") 53 ] 54 55 containerHasHeight height = 56 Query.has 57 [ class "dashboard-team-pipelines" 58 , style "height" <| String.fromInt height ++ "px" 59 ] 60 61 loadDashboardWithSize width height = 62 Common.init "/" 63 |> Application.handleCallback 64 (Callback.GotViewport Dashboard <| 65 Ok <| 66 viewportWithSize width height 67 ) 68 |> Tuple.first 69 in 70 describe "dashboard rendering" 71 [ test "renders the pipelines container as position relative" <| 72 \_ -> 73 loadDashboardWithSize 600 600 74 |> Application.handleCallback 75 (Callback.AllPipelinesFetched <| 76 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 77 ) 78 |> Tuple.first 79 |> Common.queryView 80 |> Query.has 81 [ class "dashboard-team-pipelines" 82 , style "position" "relative" 83 ] 84 , test "fetches the viewport of the scrollable area on load" <| 85 \_ -> 86 Application.init 87 { turbulenceImgSrc = "" 88 , notFoundImgSrc = "notfound.svg" 89 , csrfToken = "csrf_token" 90 , authToken = "" 91 , pipelineRunningKeyframes = "pipeline-running" 92 } 93 { protocol = Url.Http 94 , host = "" 95 , port_ = Nothing 96 , path = "/" 97 , query = Nothing 98 , fragment = Nothing 99 } 100 |> Tuple.second 101 |> Common.contains (GetViewportOf Dashboard) 102 , test "fetches the viewport of the scrollable area when the window is resized" <| 103 \_ -> 104 loadDashboardWithSize 600 600 105 |> Application.handleDelivery 106 (Subscription.WindowResized 800 600) 107 |> Tuple.second 108 |> Common.contains (GetViewportOf Dashboard) 109 , test "fetches the viewport of the scrollable area when the sidebar is opened" <| 110 \_ -> 111 loadDashboardWithSize 600 600 112 |> Application.update (Update <| Click HamburgerMenu) 113 |> Tuple.second 114 |> Common.contains (GetViewportOf Dashboard) 115 , test "fetches the viewport of the scrollable area when the sidebar state is loaded" <| 116 \_ -> 117 loadDashboardWithSize 600 600 118 |> Application.handleDelivery 119 (SideBarStateReceived 120 (Ok 121 { isOpen = True 122 , width = 275 123 } 124 ) 125 ) 126 |> Tuple.second 127 |> Common.contains (GetViewportOf Dashboard) 128 , test "fetches the viewport of the scrollable area when pipelines are fetched" <| 129 \_ -> 130 loadDashboardWithSize 600 600 131 |> Application.handleCallback 132 (Callback.AllPipelinesFetched (Ok [])) 133 |> Tuple.second 134 |> Common.contains (GetViewportOf Dashboard) 135 , test "renders pipeline cards in a single column grid when the viewport is narrow" <| 136 \_ -> 137 loadDashboardWithSize 300 600 138 |> Application.handleCallback 139 (Callback.AllPipelinesFetched <| 140 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 141 ) 142 |> Tuple.first 143 |> Common.queryView 144 |> Query.find [ class "dashboard-team-pipelines" ] 145 |> Expect.all 146 [ findPipelineCard "pipeline-0" 147 >> hasBounds 148 { x = 25 149 , y = 0 150 , width = 272 151 , height = 268 152 } 153 , findPipelineCard "pipeline-1" 154 >> hasBounds 155 { x = 25 156 , y = 268 + 25 157 , width = 272 158 , height = 268 159 } 160 ] 161 , test "renders pipeline cards in a multi-column grid when the viewport is wide" <| 162 \_ -> 163 loadDashboardWithSize 650 200 164 |> Application.handleCallback 165 (Callback.AllPipelinesFetched <| 166 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 167 ) 168 |> Tuple.first 169 |> Common.queryView 170 |> Query.find [ class "dashboard-team-pipelines" ] 171 |> Expect.all 172 [ findPipelineCard "pipeline-0" 173 >> hasBounds 174 { x = 25 175 , y = 0 176 , width = 272 177 , height = 268 178 } 179 , findPipelineCard "pipeline-1" 180 >> hasBounds 181 { x = 25 * 2 + 272 182 , y = 0 183 , width = 272 184 , height = 268 185 } 186 ] 187 , test "ignores viewport updates for DOM elements other than the dashboard" <| 188 \_ -> 189 loadDashboardWithSize 650 200 190 |> Application.handleCallback 191 (Callback.AllPipelinesFetched <| 192 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 193 ) 194 |> Tuple.first 195 |> Application.handleCallback 196 (Callback.GotViewport LoginButton <| 197 Ok <| 198 viewportWithSize 100 50 199 ) 200 |> Tuple.first 201 |> Common.queryView 202 |> Query.find [ class "dashboard-team-pipelines" ] 203 |> Expect.all 204 [ findPipelineCard "pipeline-0" 205 >> hasBounds 206 { x = 25 207 , y = 0 208 , width = 272 209 , height = 268 210 } 211 , findPipelineCard "pipeline-1" 212 >> hasBounds 213 { x = 25 * 2 + 272 214 , y = 0 215 , width = 272 216 , height = 268 217 } 218 ] 219 , test "pipelines with many jobs are rendered as cards spanning several rows" <| 220 \_ -> 221 loadDashboardWithSize 600 300 222 |> Application.handleCallback 223 (Callback.AllPipelinesFetched <| 224 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 225 ) 226 |> Tuple.first 227 |> Application.handleCallback 228 (Callback.AllJobsFetched <| 229 Ok <| 230 jobsWithHeight 0 15 231 ) 232 |> Tuple.first 233 |> Common.queryView 234 |> Query.find [ class "dashboard-team-pipelines" ] 235 |> Expect.all 236 [ findPipelineCard "pipeline-0" 237 >> hasBounds 238 { x = 25 239 , y = 0 240 , width = 272 241 , height = 268 * 2 + 25 242 } 243 , findPipelineCard "pipeline-1" 244 >> hasBounds 245 { x = 25 * 2 + 272 246 , y = 0 247 , width = 272 248 , height = 268 249 } 250 , containerHasHeight <| (268 + 25) * 2 251 ] 252 , test "pipelines with many dependant jobs are rendered as spanning multiple columns" <| 253 \_ -> 254 loadDashboardWithSize 950 300 255 |> Application.handleCallback 256 (Callback.AllPipelinesFetched <| 257 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 258 ) 259 |> Tuple.first 260 |> Application.handleCallback 261 (Callback.AllJobsFetched <| 262 Ok <| 263 jobsWithDepth 0 15 264 ) 265 |> Tuple.first 266 |> Common.queryView 267 |> Query.find [ class "dashboard-team-pipelines" ] 268 |> Expect.all 269 [ findPipelineCard "pipeline-0" 270 >> hasBounds 271 { x = 25 272 , y = 0 273 , width = 272 * 2 + 25 274 , height = 268 275 } 276 , findPipelineCard "pipeline-1" 277 >> hasBounds 278 { x = 25 + 2 * (272 + 25) 279 , y = 0 280 , width = 272 281 , height = 268 282 } 283 ] 284 , test "wraps cards to the next row" <| 285 \_ -> 286 loadDashboardWithSize 600 500 287 |> Application.handleCallback 288 (Callback.AllPipelinesFetched <| 289 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 290 ) 291 |> Tuple.first 292 |> Common.queryView 293 |> Query.find [ class "dashboard-team-pipelines" ] 294 |> Expect.all 295 [ findPipelineCard "pipeline-0" 296 >> hasBounds 297 { x = 25 298 , y = 0 299 , width = 272 300 , height = 268 301 } 302 , findPipelineCard "pipeline-1" 303 >> hasBounds 304 { x = 25 * 2 + 272 305 , y = 0 306 , width = 272 307 , height = 268 308 } 309 , findPipelineCard "pipeline-2" 310 >> hasBounds 311 { x = 25 312 , y = 268 + 25 313 , width = 272 314 , height = 268 315 } 316 , containerHasHeight <| (268 + 25) * 2 317 ] 318 , test "sets the container height to the height of the cards" <| 319 \_ -> 320 loadDashboardWithSize 300 600 321 |> Application.handleCallback 322 (Callback.AllPipelinesFetched <| 323 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 324 ) 325 |> Tuple.first 326 |> Common.queryView 327 |> containerHasHeight ((268 + 25) * 2) 328 , test "doesn't render rows below the viewport" <| 329 \_ -> 330 loadDashboardWithSize 300 300 331 |> Application.handleCallback 332 (Callback.AllPipelinesFetched <| 333 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 334 ) 335 |> Tuple.first 336 |> Common.queryView 337 |> Query.find [ class "dashboard-team-pipelines" ] 338 |> Query.hasNot [ class "pipeline-wrapper", containing [ text "pipeline-2" ] ] 339 , test "body has a scroll handler" <| 340 \_ -> 341 loadDashboardWithSize 300 300 342 |> Application.handleCallback 343 (Callback.AllPipelinesFetched <| 344 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 345 ) 346 |> Tuple.first 347 |> Common.queryView 348 |> Query.find [ id "dashboard" ] 349 |> Event.simulate 350 (Event.custom "scroll" <| 351 Encode.object 352 [ ( "target" 353 , Encode.object 354 [ ( "clientHeight", Encode.int 0 ) 355 , ( "scrollTop", Encode.int 0 ) 356 , ( "scrollHeight", Encode.int 0 ) 357 ] 358 ) 359 ] 360 ) 361 |> Event.expect 362 (Update <| 363 Scrolled 364 { scrollHeight = 0 365 , scrollTop = 0 366 , clientHeight = 0 367 } 368 ) 369 , test "rows are hidden as they are scrolled out of view" <| 370 \_ -> 371 loadDashboardWithSize 600 200 372 |> Application.handleCallback 373 (Callback.AllPipelinesFetched <| 374 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 375 ) 376 |> Tuple.first 377 |> Application.update 378 (Update <| 379 Scrolled 380 { scrollTop = 700 381 , scrollHeight = 3240 382 , clientHeight = 200 383 } 384 ) 385 |> Tuple.first 386 |> Common.queryView 387 |> Query.find [ class "dashboard-team-pipelines" ] 388 |> Query.hasNot [ class "pipeline-wrapper", containing [ text "pipeline-0" ] ] 389 , test "tall cards are not hidden when only its top row is scrolled out of view" <| 390 \_ -> 391 loadDashboardWithSize 600 300 392 |> Application.handleCallback 393 (Callback.AllPipelinesFetched <| 394 Ok [ Data.pipeline "team" 0 ] 395 ) 396 |> Tuple.first 397 |> Application.handleCallback 398 (Callback.AllJobsFetched <| 399 Ok <| 400 jobsWithHeight 0 30 401 ) 402 |> Tuple.first 403 |> Application.update 404 (Update <| 405 Scrolled 406 { scrollTop = 600 407 , scrollHeight = 3240 408 , clientHeight = 300 409 } 410 ) 411 |> Tuple.first 412 |> Common.queryView 413 |> Query.find [ class "dashboard-team-pipelines" ] 414 |> Query.has [ class "pipeline-wrapper", containing [ text "pipeline-0" ] ] 415 , test "groups that are outside the viewport have no visible pipelines" <| 416 \_ -> 417 loadDashboardWithSize 300 300 418 |> Application.handleCallback 419 (Callback.AllPipelinesFetched <| 420 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team-2" 2 ] 421 ) 422 |> Tuple.first 423 |> Common.queryView 424 |> Query.find [ id "team-2" ] 425 |> Query.hasNot [ class "pipeline-wrapper" ] 426 , test "groups that are scrolled into view have visible pipelines" <| 427 \_ -> 428 loadDashboardWithSize 300 300 429 |> Application.handleCallback 430 (Callback.AllPipelinesFetched <| 431 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team-2" 2 ] 432 ) 433 |> Tuple.first 434 |> Application.update 435 (Update <| 436 Scrolled 437 { scrollTop = 600 438 , scrollHeight = 3240 439 , clientHeight = 200 440 } 441 ) 442 |> Tuple.first 443 |> Common.queryView 444 |> Query.find [ id "team-2" ] 445 |> Query.has [ class "pipeline-wrapper", containing [ text "pipeline-2" ] ] 446 , test "pipeline wrapper has a z-index of 1 when hovering over a job" <| 447 \_ -> 448 loadDashboardWithSize 300 300 449 |> Application.handleCallback 450 (Callback.AllPipelinesFetched <| 451 Ok [ Data.pipeline "team" 0 ] 452 ) 453 |> Tuple.first 454 |> Application.update 455 (Update <| 456 Hover <| 457 Just <| 458 JobPreview AllPipelinesSection (Data.jobId |> Data.withPipelineName "pipeline-0") 459 ) 460 |> Tuple.first 461 |> Common.queryView 462 |> Query.find [ class "dashboard-team-pipelines" ] 463 |> Query.has [ class "pipeline-wrapper", style "z-index" "1" ] 464 , test "pipeline wrapper has a z-index of 1 when hovering over the wrapper" <| 465 \_ -> 466 loadDashboardWithSize 300 300 467 |> Application.handleCallback 468 (Callback.AllPipelinesFetched <| 469 Ok [ Data.pipeline "team" 0 ] 470 ) 471 |> Tuple.first 472 |> Application.update 473 (Update <| 474 Hover <| 475 Just <| 476 PipelineWrapper (Data.pipelineId |> Data.withPipelineName "pipeline-0") 477 ) 478 |> Tuple.first 479 |> Common.queryView 480 |> Query.find [ class "dashboard-team-pipelines" ] 481 |> Query.has [ class "pipeline-wrapper", style "z-index" "1" ] 482 , test "pipeline wrapper responds to mouse over" <| 483 \_ -> 484 loadDashboardWithSize 300 300 485 |> Application.handleCallback 486 (Callback.AllPipelinesFetched <| 487 Ok [ Data.pipeline "team" 0 ] 488 ) 489 |> Tuple.first 490 |> Common.queryView 491 |> Query.find [ class "pipeline-wrapper" ] 492 |> Event.simulate Event.mouseOver 493 |> Event.expect 494 (Update <| 495 Hover <| 496 Just <| 497 PipelineWrapper (Data.pipelineId |> Data.withPipelineName "pipeline-0") 498 ) 499 , test "pipeline wrapper responds to mouse out" <| 500 \_ -> 501 loadDashboardWithSize 300 300 502 |> Application.handleCallback 503 (Callback.AllPipelinesFetched <| 504 Ok [ Data.pipeline "team" 0 ] 505 ) 506 |> Tuple.first 507 |> Common.queryView 508 |> Query.find [ class "pipeline-wrapper" ] 509 |> Event.simulate Event.mouseOut 510 |> Event.expect (Update <| Hover Nothing) 511 , describe "drop areas" <| 512 [ test "renders a drop area over each pipeline card" <| 513 \_ -> 514 loadDashboardWithSize 600 500 515 |> Application.handleCallback 516 (Callback.AllPipelinesFetched <| 517 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 518 ) 519 |> Tuple.first 520 |> Common.queryView 521 |> Query.find [ class "dashboard-team-pipelines" ] 522 |> Query.findAll [ class "drop-area" ] 523 |> Expect.all 524 [ Query.index 0 525 >> hasBounds 526 { x = 0 527 , y = 0 528 , width = 272 + 25 529 , height = 268 530 } 531 , Query.index 1 532 >> hasBounds 533 { x = 272 + 25 534 , y = 0 535 , width = 272 + 25 536 , height = 268 537 } 538 , Query.index 2 539 >> hasBounds 540 { x = 0 541 , y = 268 + 25 542 , width = 272 + 25 543 , height = 268 544 } 545 ] 546 , test "does not render drop areas for rows that are not visible" <| 547 \_ -> 548 loadDashboardWithSize 300 300 549 |> Application.handleCallback 550 (Callback.AllPipelinesFetched <| 551 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1, Data.pipeline "team" 2 ] 552 ) 553 |> Tuple.first 554 |> Common.queryView 555 |> Query.find [ class "dashboard-team-pipelines" ] 556 |> Query.findAll [ class "drop-area" ] 557 |> Query.count (Expect.equal 2) 558 , test "renders the final drop area to the right of the last card" <| 559 \_ -> 560 loadDashboardWithSize 600 300 561 |> Application.handleCallback 562 (Callback.AllPipelinesFetched <| 563 Ok [ Data.pipeline "team" 0 ] 564 ) 565 |> Tuple.first 566 |> Common.queryView 567 |> Query.find [ class "dashboard-team-pipelines" ] 568 |> Query.findAll [ class "drop-area" ] 569 |> Query.index -1 570 |> hasBounds 571 { x = 272 + 25 572 , y = 0 573 , width = 272 + 25 574 , height = 268 575 } 576 , test "renders the drop area up one row when the card breaks the row, but there is space for a smaller card" <| 577 \_ -> 578 loadDashboardWithSize 600 500 579 |> Application.handleCallback 580 (Callback.AllPipelinesFetched <| 581 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 582 ) 583 |> Tuple.first 584 |> Application.handleCallback 585 (Callback.AllJobsFetched <| 586 Ok <| 587 jobsWithDepth 1 15 588 ) 589 |> Tuple.first 590 |> Common.queryView 591 |> Query.find [ class "dashboard-team-pipelines" ] 592 |> Query.findAll [ class "drop-area" ] 593 |> Expect.all 594 [ Query.index 0 595 >> hasBounds 596 { x = 0 597 , y = 0 598 , width = 272 + 25 599 , height = 268 600 } 601 , Query.index 1 602 >> hasBounds 603 { x = 272 + 25 604 , y = 0 605 , width = 272 + 25 606 , height = 268 607 } 608 ] 609 ] 610 , describe "when there are favorited pipelines" <| 611 let 612 gotFavoritedPipelines ids = 613 Application.handleDelivery 614 (Subscription.FavoritedPipelinesReceived <| Ok <| Set.fromList ids) 615 616 findHeader t = 617 Query.find [ class "headers" ] 618 >> Query.find [ class "header", containing [ text t ] ] 619 in 620 [ test "renders a favorites pipeline section" <| 621 \_ -> 622 loadDashboardWithSize 600 500 623 |> Application.handleCallback 624 (Callback.AllPipelinesFetched <| 625 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 626 ) 627 |> Tuple.first 628 |> gotFavoritedPipelines [ 0 ] 629 |> Tuple.first 630 |> Common.queryView 631 |> Query.has [ id "dashboard-favorite-pipelines" ] 632 , test "renders pipeline cards in the favorites section" <| 633 \_ -> 634 loadDashboardWithSize 600 500 635 |> Application.handleCallback 636 (Callback.AllPipelinesFetched <| 637 Ok [ Data.pipeline "team" 0 ] 638 ) 639 |> Tuple.first 640 |> gotFavoritedPipelines [ 0 ] 641 |> Tuple.first 642 |> Common.queryView 643 |> Query.find [ id "dashboard-favorite-pipelines" ] 644 |> findPipelineCard "pipeline-0" 645 |> hasBounds 646 { x = 25 647 , y = 60 648 , width = 272 649 , height = 268 650 } 651 , test "favorite section has the height of the cards" <| 652 \_ -> 653 loadDashboardWithSize 300 500 654 |> Application.handleCallback 655 (Callback.AllPipelinesFetched <| 656 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 657 ) 658 |> Tuple.first 659 |> gotFavoritedPipelines [ 0, 1 ] 660 |> Tuple.first 661 |> Common.queryView 662 |> Query.find [ id "dashboard-favorite-pipelines" ] 663 |> Query.has 664 [ style "height" <| 665 String.fromFloat (2 * 268 + 2 * 60) 666 ++ "px" 667 ] 668 , test "offsets all pipelines section by height of the favorites section" <| 669 \_ -> 670 loadDashboardWithSize 300 200 671 |> Application.handleCallback 672 (Callback.AllPipelinesFetched <| 673 Ok [ Data.pipeline "team" 0, Data.pipeline "team" 1 ] 674 ) 675 |> Tuple.first 676 |> gotFavoritedPipelines [ 0, 1 ] 677 |> Tuple.first 678 |> Common.queryView 679 |> Query.find [ class "dashboard-team-pipelines" ] 680 |> Query.hasNot [ class "pipeline-wrapper", containing [ text "pipeline-0" ] ] 681 , test "renders team header above the first pipeline card" <| 682 \_ -> 683 loadDashboardWithSize 300 200 684 |> Application.handleCallback 685 (Callback.AllPipelinesFetched <| 686 Ok [ Data.pipeline "team" 0 ] 687 ) 688 |> Tuple.first 689 |> gotFavoritedPipelines [ 0 ] 690 |> Tuple.first 691 |> Common.queryView 692 |> Query.find [ id "dashboard-favorite-pipelines" ] 693 |> findHeader "team" 694 |> hasBounds { x = 25, y = 0, width = 272, height = 60 } 695 , test "renders multiple teams' headers" <| 696 \_ -> 697 loadDashboardWithSize 600 200 698 |> Application.handleCallback 699 (Callback.AllPipelinesFetched <| 700 Ok [ Data.pipeline "team1" 0, Data.pipeline "team2" 1 ] 701 ) 702 |> Tuple.first 703 |> gotFavoritedPipelines [ 0, 1 ] 704 |> Tuple.first 705 |> Common.queryView 706 |> Query.find [ id "dashboard-favorite-pipelines" ] 707 |> Expect.all 708 [ findHeader "team1" 709 >> hasBounds { x = 25, y = 0, width = 272, height = 60 } 710 , findHeader "team2" 711 >> hasBounds { x = 272 + 25 * 2, y = 0, width = 272, height = 60 } 712 ] 713 , test "renders one header per team" <| 714 \_ -> 715 loadDashboardWithSize 600 200 716 |> Application.handleCallback 717 (Callback.AllPipelinesFetched <| 718 Ok [ Data.pipeline "team1" 0, Data.pipeline "team1" 1 ] 719 ) 720 |> Tuple.first 721 |> gotFavoritedPipelines [ 0, 1 ] 722 |> Tuple.first 723 |> Common.queryView 724 |> Query.find [ id "dashboard-favorite-pipelines" ] 725 |> findHeader "team1" 726 |> hasBounds { x = 25, y = 0, width = 272 * 2 + 25, height = 60 } 727 , test "renders a 'continued' header when a team spans multiple rows" <| 728 \_ -> 729 loadDashboardWithSize 300 600 730 |> Application.handleCallback 731 (Callback.AllPipelinesFetched <| 732 Ok [ Data.pipeline "team1" 0, Data.pipeline "team1" 1 ] 733 ) 734 |> Tuple.first 735 |> gotFavoritedPipelines [ 0, 1 ] 736 |> Tuple.first 737 |> Common.queryView 738 |> Query.find [ id "dashboard-favorite-pipelines" ] 739 |> findHeader "team1 (continued)" 740 |> hasBounds { x = 25, y = 268 + 60, width = 272, height = 60 } 741 ] 742 ] 743 744 745 jobsWithHeight : Int -> Int -> List Concourse.Job 746 jobsWithHeight pipelineID height = 747 List.range 1 height 748 |> List.map 749 (\i -> 750 let 751 job = 752 Data.job pipelineID 753 in 754 { job | name = String.fromInt i } 755 ) 756 757 758 jobsWithDepth : Int -> Int -> List Concourse.Job 759 jobsWithDepth pipelineID depth = 760 let 761 job = 762 Data.job pipelineID 763 in 764 if depth < 1 then 765 [] 766 767 else if depth == 1 then 768 [ { job 769 | name = "1" 770 , inputs = 771 [ { name = "" 772 , resource = "" 773 , passed = [] 774 , trigger = False 775 } 776 ] 777 } 778 ] 779 780 else 781 { job 782 | name = String.fromInt depth 783 , inputs = 784 [ { name = "" 785 , resource = "" 786 , passed = [ String.fromInt <| depth - 1 ] 787 , trigger = False 788 } 789 ] 790 } 791 :: (jobsWithDepth pipelineID <| depth - 1)