1 require 'integration_helper'
3 class ProjectsTest < ActionDispatch::IntegrationTest
8 test 'Check collection count for A Project in the tab pane titles' do
9 project_uuid = api_fixture('groups')['aproject']['uuid']
10 visit page_with_token 'active', '/projects/' + project_uuid
12 collection_count = page.all("[data-pk*='collection']").count
13 assert_selector '#Data_collections-tab span', text: "(#{collection_count})"
16 test 'Find a project and edit its description' do
17 visit page_with_token 'active', '/'
18 find("#projects-menu").click
19 find(".dropdown-menu a", text: "A Project").click
20 within('.container-fluid', text: api_fixture('groups')['aproject']['name']) do
21 find('span', text: api_fixture('groups')['aproject']['name']).click
22 within('.arv-description-as-subtitle') do
23 find('.fa-pencil').click
24 find('.editable-input textarea').set('I just edited this.')
25 find('.editable-submit').click
30 assert(find?('.container-fluid', text: 'I just edited this.'),
31 "Description update did not survive page refresh")
34 test 'Find a project and edit description to textile description' do
35 visit page_with_token 'active', '/'
36 find("#projects-menu").click
37 find(".dropdown-menu a", text: "A Project").click
38 within('.container-fluid', text: api_fixture('groups')['aproject']['name']) do
39 find('span', text: api_fixture('groups')['aproject']['name']).click
40 within('.arv-description-as-subtitle') do
41 find('.fa-pencil').click
42 find('.editable-input textarea').set('<p>*Textile description for A project* - "take me home":/ </p><p>And a new paragraph in description.</p>')
43 find('.editable-submit').click
50 assert_no_text '*Textile description for A project*'
51 assert(find?('.container-fluid', text: 'Textile description for A project'),
52 "Description update did not survive page refresh")
53 assert(find?('.container-fluid', text: 'And a new paragraph in description'),
54 "Description did not contain the expected new paragraph")
55 assert(page.has_link?("take me home"), "link not found in description")
57 click_link 'take me home'
60 assert(page.has_text?('Active pipelines'), 'Active pipelines - not found on dashboard')
63 test 'Find a project and edit description to html description' do
64 visit page_with_token 'active', '/'
65 find("#projects-menu").click
66 find(".dropdown-menu a", text: "A Project").click
67 within('.container-fluid', text: api_fixture('groups')['aproject']['name']) do
68 find('span', text: api_fixture('groups')['aproject']['name']).click
69 within('.arv-description-as-subtitle') do
70 find('.fa-pencil').click
71 find('.editable-input textarea').set('<br>Textile description for A project</br> - <a href="/">take me home</a>')
72 find('.editable-submit').click
77 assert(find?('.container-fluid', text: 'Textile description for A project'),
78 "Description update did not survive page refresh")
79 assert(!find?('.container-fluid', text: '<br>Textile description for A project</br>'),
80 "Textile description is displayed with uninterpreted formatting characters")
81 assert(page.has_link?("take me home"),"link not found in description")
82 click_link 'take me home'
83 assert page.has_text?('Active pipelines')
86 test 'Find a project and edit description to textile description with link to object' do
87 visit page_with_token 'active', '/'
88 find("#projects-menu").click
89 find(".dropdown-menu a", text: "A Project").click
90 within('.container-fluid', text: api_fixture('groups')['aproject']['name']) do
91 find('span', text: api_fixture('groups')['aproject']['name']).click
92 within('.arv-description-as-subtitle') do
93 find('.fa-pencil').click
94 find('.editable-input textarea').set('*Textile description for A project* - "go to sub-project":' + api_fixture('groups')['asubproject']['uuid'] + "'")
95 find('.editable-submit').click
100 assert(find?('.container-fluid', text: 'Textile description for A project'),
101 "Description update did not survive page refresh")
102 assert(!find?('.container-fluid', text: '*Textile description for A project*'),
103 "Textile description is displayed with uninterpreted formatting characters")
104 assert(page.has_link?("go to sub-project"), "link not found in description")
105 click_link 'go to sub-project'
106 assert(page.has_text?(api_fixture('groups')['asubproject']['name']), 'sub-project name not found after clicking link')
109 test 'Add a new name, then edit it, without creating a duplicate' do
110 project_uuid = api_fixture('groups')['aproject']['uuid']
111 specimen_uuid = api_fixture('traits')['owned_by_aproject_with_no_name']['uuid']
112 visit page_with_token 'active', '/projects/' + project_uuid
113 click_link 'Other objects'
114 within '.selection-action-container' do
115 # Wait for the tab to load:
116 assert_selector 'tr[data-kind="arvados#trait"]'
117 within first('tr', text: 'Trait') do
118 find(".fa-pencil").click
119 find('.editable-input input').set('Now I have a name.')
120 find('.glyphicon-ok').click
121 assert_selector '.editable', text: 'Now I have a name.'
122 find(".fa-pencil").click
123 find('.editable-input input').set('Now I have a new name.')
124 find('.glyphicon-ok').click
127 assert_selector '.editable', text: 'Now I have a new name.'
130 click_link 'Other objects'
131 within '.selection-action-container' do
132 find '.editable', text: 'Now I have a new name.'
133 assert_no_selector '.editable', text: 'Now I have a name.'
137 test 'Create a project and move it into a different project' do
138 visit page_with_token 'active', '/projects'
139 find("#projects-menu").click
140 find(".dropdown-menu a", text: "Home").click
141 find('.btn', text: "Add a subproject").click
144 find('.fa-pencil').click
145 find('.editable-input input').set('Project 1234')
146 find('.glyphicon-ok').click
151 find("#projects-menu").click
152 find(".dropdown-menu a", text: "Home").click
153 find('.btn', text: "Add a subproject").click
155 find('.fa-pencil').click
156 find('.editable-input input').set('Project 5678')
157 find('.glyphicon-ok').click
161 click_link 'Move project...'
162 find('.selectable', text: 'Project 1234').click
163 find('.modal-footer a,button', text: 'Move').click
166 # Wait for the page to refresh and show the new parent in Sharing panel
168 assert(page.has_link?("Project 1234"),
169 "Project 5678 should now be inside project 1234")
172 def show_project_using(auth_key, proj_key='aproject')
173 project_uuid = api_fixture('groups')[proj_key]['uuid']
174 visit(page_with_token(auth_key, "/projects/#{project_uuid}"))
175 assert(page.has_text?("A Project"), "not on expected project page")
179 find('#project_sharing').all('tr')
182 def add_share_and_check(share_type, name, obj=nil)
183 assert(page.has_no_text?(name), "project is already shared with #{name}")
184 start_share_count = share_rows.size
185 click_on("Share with #{share_type}")
186 within(".modal-container") do
187 # Order is important here: we should find something that appears in the
188 # modal before we make any assertions about what's not in the modal.
189 # Otherwise, the not-included assertions might falsely pass because
190 # the modal hasn't loaded yet.
191 find(".selectable", text: name).click
192 assert(has_no_selector?(".modal-dialog-preview-pane"),
193 "preview pane available in sharing dialog")
194 if share_type == 'users' and obj and obj['email']
195 assert(page.has_text?(obj['email']), "Did not find user's email")
197 assert_raises(Capybara::ElementNotFound,
198 "Projects pulldown available from sharing dialog") do
199 click_on "All projects"
203 using_wait_time(Capybara.default_wait_time * 3) do
204 assert(page.has_link?(name),
205 "new share was not added to sharing table")
206 assert_equal(start_share_count + 1, share_rows.size,
207 "new share did not add row to sharing table")
211 def modify_share_and_check(name)
212 start_rows = share_rows
213 link_row = start_rows.select { |row| row.has_text?(name) }
214 assert_equal(1, link_row.size, "row with new permission not found")
215 within(link_row.first) do
217 select("Write", from: "share_change_level")
218 click_on("editable-submit")
219 assert(has_link?("Write"),
220 "failed to change access level on new share")
222 if Capybara.current_driver == :selenium
223 page.driver.browser.switch_to.alert.accept
225 # poltergeist returns true for confirm(), so we don't need to accept.
229 using_wait_time(Capybara.default_wait_time * 3) do
230 assert(page.has_no_text?(name),
231 "new share row still exists after being revoked")
232 assert_equal(start_rows.size - 1, share_rows.size,
233 "revoking share did not remove row from sharing table")
237 test "project viewer can't see project sharing tab" do
238 show_project_using("project_viewer")
239 assert(page.has_no_link?("Sharing"),
240 "read-only project user sees sharing tab")
243 test "project owner can manage sharing for another user" do
244 add_user = api_fixture('users')['future_project_user']
245 new_name = ["first_name", "last_name"].map { |k| add_user[k] }.join(" ")
247 show_project_using("active")
249 add_share_and_check("users", new_name, add_user)
250 modify_share_and_check(new_name)
253 test "project owner can manage sharing for another group" do
254 new_name = api_fixture('groups')['future_project_viewing_group']['name']
256 show_project_using("active")
258 add_share_and_check("groups", new_name)
259 modify_share_and_check(new_name)
262 test "'share with group' listing does not offer projects" do
263 show_project_using("active")
265 click_on "Share with groups"
266 good_uuid = api_fixture("groups")["private"]["uuid"]
267 assert(page.has_selector?(".selectable[data-object-uuid=\"#{good_uuid}\"]"),
268 "'share with groups' listing missing owned user group")
269 bad_uuid = api_fixture("groups")["asubproject"]["uuid"]
270 assert(page.has_no_selector?(".selectable[data-object-uuid=\"#{bad_uuid}\"]"),
271 "'share with groups' listing includes project")
275 ['Move',api_fixture('collections')['collection_to_move_around_in_aproject'],
276 api_fixture('groups')['aproject'],api_fixture('groups')['asubproject']],
277 ['Remove',api_fixture('collections')['collection_to_move_around_in_aproject'],
278 api_fixture('groups')['aproject']],
279 ['Copy',api_fixture('collections')['collection_to_move_around_in_aproject'],
280 api_fixture('groups')['aproject'],api_fixture('groups')['asubproject']],
281 ['Remove',api_fixture('collections')['collection_in_aproject_with_same_name_as_in_home_project'],
282 api_fixture('groups')['aproject'],nil,true],
283 ].each do |action, my_collection, src, dest=nil, expect_name_change=nil|
284 test "selection #{action} -> #{expect_name_change.inspect} for project" do
285 perform_selection_action src, dest, my_collection, action
289 assert page.has_text?(my_collection['name']), 'Collection not found in src project after copy'
290 visit page_with_token 'active', '/'
291 find("#projects-menu").click
292 find(".dropdown-menu a", text: dest['name']).click
293 assert page.has_text?(my_collection['name']), 'Collection not found in dest project after copy'
296 assert page.has_no_text?(my_collection['name']), 'Collection still found in src project after move'
297 visit page_with_token 'active', '/'
298 find("#projects-menu").click
299 find(".dropdown-menu a", text: dest['name']).click
300 assert page.has_text?(my_collection['name']), 'Collection not found in dest project after move'
303 assert page.has_no_text?(my_collection['name']), 'Collection still found in src project after remove'
304 visit page_with_token 'active', '/'
305 find("#projects-menu").click
306 find(".dropdown-menu a", text: "Home").click
307 assert page.has_text?(my_collection['name']), 'Collection not found in home project after remove'
308 if expect_name_change
309 assert page.has_text?(my_collection['name']+' removed from ' + src['name']),
310 'Collection with update name is not found in home project after remove'
316 def perform_selection_action src, dest, item, action
317 visit page_with_token 'active', '/'
318 find("#projects-menu").click
319 find(".dropdown-menu a", text: src['name']).click
320 assert page.has_text?(item['name']), 'Collection not found in src project'
322 within('tr', text: item['name']) do
323 find('input[type=checkbox]').click
326 click_button 'Selection'
328 within('.selection-action-container') do
329 assert page.has_text?("Compare selected"), "Compare selected link text not found"
330 assert page.has_link?("Copy selected"), "Copy selected link not found"
331 assert page.has_link?("Move selected"), "Move selected link not found"
332 assert page.has_link?("Remove selected"), "Remove selected link not found"
334 click_link "#{action} selected"
337 # select the destination project if a Copy or Move action is being performed
338 if action == 'Copy' || action == 'Move'
339 within(".modal-container") do
340 find('.selectable', text: dest['name']).click
341 find('.modal-footer a,button', text: action).click
347 # Test copy action state. It should not be available when a subproject is selected.
348 test "copy action is disabled when a subproject is selected" do
349 my_project = api_fixture('groups')['aproject']
350 my_collection = api_fixture('collections')['collection_to_move_around_in_aproject']
351 my_subproject = api_fixture('groups')['asubproject']
353 # verify that selection options are disabled on the project until an item is selected
354 visit page_with_token 'active', '/'
355 find("#projects-menu").click
356 find(".dropdown-menu a", text: my_project['name']).click
358 click_button 'Selection'
359 within('.selection-action-container') do
360 assert_selector 'li.disabled', text: 'Create new collection with selected collections'
361 assert_selector 'li.disabled', text: 'Compare selected'
362 assert_selector 'li.disabled', text: 'Copy selected'
363 assert_selector 'li.disabled', text: 'Move selected'
364 assert_selector 'li.disabled', text: 'Remove selected'
367 # select collection and verify links are enabled
368 visit page_with_token 'active', '/'
369 find("#projects-menu").click
370 find(".dropdown-menu a", text: my_project['name']).click
371 assert page.has_text?(my_collection['name']), 'Collection not found in project'
373 within('tr', text: my_collection['name']) do
374 find('input[type=checkbox]').click
377 click_button 'Selection'
378 within('.selection-action-container') do
379 assert_no_selector 'li.disabled', text: 'Create new collection with selected collections'
380 assert_selector 'li', text: 'Create new collection with selected collections'
381 assert_selector 'li.disabled', text: 'Compare selected'
382 assert_no_selector 'li.disabled', text: 'Copy selected'
383 assert_selector 'li', text: 'Copy selected'
384 assert_no_selector 'li.disabled', text: 'Move selected'
385 assert_selector 'li', text: 'Move selected'
386 assert_no_selector 'li.disabled', text: 'Remove selected'
387 assert_selector 'li', text: 'Remove selected'
390 # select subproject and verify that copy action is disabled
391 visit page_with_token 'active', '/'
392 find("#projects-menu").click
393 find(".dropdown-menu a", text: my_project['name']).click
395 click_link 'Subprojects'
396 assert page.has_text?(my_subproject['name']), 'Subproject not found in project'
398 within('tr', text: my_subproject['name']) do
399 find('input[type=checkbox]').click
402 click_button 'Selection'
403 within('.selection-action-container') do
404 assert_selector 'li.disabled', text: 'Create new collection with selected collections'
405 assert_selector 'li.disabled', text: 'Compare selected'
406 assert_selector 'li.disabled', text: 'Copy selected'
407 assert_no_selector 'li.disabled', text: 'Move selected'
408 assert_selector 'li', text: 'Move selected'
409 assert_no_selector 'li.disabled', text: 'Remove selected'
410 assert_selector 'li', text: 'Remove selected'
413 # select subproject and a collection and verify that copy action is still disabled
414 visit page_with_token 'active', '/'
415 find("#projects-menu").click
416 find(".dropdown-menu a", text: my_project['name']).click
418 click_link 'Subprojects'
419 assert page.has_text?(my_subproject['name']), 'Subproject not found in project'
421 within('tr', text: my_subproject['name']) do
422 find('input[type=checkbox]').click
425 click_link 'Data collections'
426 assert page.has_text?(my_collection['name']), 'Collection not found in project'
428 within('tr', text: my_collection['name']) do
429 find('input[type=checkbox]').click
432 click_link 'Subprojects'
433 click_button 'Selection'
434 within('.selection-action-container') do
435 assert_selector 'li.disabled', text: 'Create new collection with selected collections'
436 assert_selector 'li.disabled', text: 'Compare selected'
437 assert_selector 'li.disabled', text: 'Copy selected'
438 assert_no_selector 'li.disabled', text: 'Move selected'
439 assert_selector 'li', text: 'Move selected'
440 assert_no_selector 'li.disabled', text: 'Remove selected'
441 assert_selector 'li', text: 'Remove selected'
445 # When project tabs are switched, only options applicable to the current tab's selections are enabled.
446 test "verify selection options when tabs are switched" do
447 my_project = api_fixture('groups')['aproject']
448 my_collection = api_fixture('collections')['collection_to_move_around_in_aproject']
449 my_subproject = api_fixture('groups')['asubproject']
451 # select subproject and a collection and verify that copy action is still disabled
452 visit page_with_token 'active', '/'
453 find("#projects-menu").click
454 find(".dropdown-menu a", text: my_project['name']).click
456 # Select a sub-project
457 click_link 'Subprojects'
458 assert page.has_text?(my_subproject['name']), 'Subproject not found in project'
460 within('tr', text: my_subproject['name']) do
461 find('input[type=checkbox]').click
464 # Select a collection
465 click_link 'Data collections'
466 assert page.has_text?(my_collection['name']), 'Collection not found in project'
468 within('tr', text: my_collection['name']) do
469 find('input[type=checkbox]').click
472 # Go back to Subprojects tab
473 click_link 'Subprojects'
474 click_button 'Selection'
475 within('.selection-action-container') do
476 assert_selector 'li.disabled', text: 'Create new collection with selected collections'
477 assert_selector 'li.disabled', text: 'Compare selected'
478 assert_selector 'li.disabled', text: 'Copy selected'
479 assert_no_selector 'li.disabled', text: 'Move selected'
480 assert_selector 'li', text: 'Move selected'
481 assert_no_selector 'li.disabled', text: 'Remove selected'
482 assert_selector 'li', text: 'Remove selected'
485 # Close the dropdown by clicking outside it.
486 find('.dropdown-toggle', text: 'Selection').find(:xpath, '..').click
488 # Go back to Data collections tab
489 find('.nav-tabs a', text: 'Data collections').click
490 click_button 'Selection'
491 within('.selection-action-container') do
492 assert_no_selector 'li.disabled', text: 'Create new collection with selected collections'
493 assert_selector 'li', text: 'Create new collection with selected collections'
494 assert_selector 'li.disabled', text: 'Compare selected'
495 assert_no_selector 'li.disabled', text: 'Copy selected'
496 assert_selector 'li', text: 'Copy selected'
497 assert_no_selector 'li.disabled', text: 'Move selected'
498 assert_selector 'li', text: 'Move selected'
499 assert_no_selector 'li.disabled', text: 'Remove selected'
500 assert_selector 'li', text: 'Remove selected'
504 # "Move selected" and "Remove selected" options should not be available when current user cannot write to the project
505 test "move selected and remove selected actions not available when current user cannot write to project" do
506 my_project = api_fixture('groups')['anonymously_accessible_project']
507 visit page_with_token 'active', "/projects/#{my_project['uuid']}"
509 click_button 'Selection'
510 within('.selection-action-container') do
511 assert_selector 'li', text: 'Create new collection with selected collections'
512 assert_selector 'li', text: 'Compare selected'
513 assert_selector 'li', text: 'Copy selected'
514 assert_no_selector 'li', text: 'Move selected'
515 assert_no_selector 'li', text: 'Remove selected'
521 ['project_viewer', false],
522 ].each do |user, expect_collection_in_aproject|
523 test "combine selected collections into new collection #{user} #{expect_collection_in_aproject}" do
524 my_project = api_fixture('groups')['aproject']
525 my_collection = api_fixture('collections')['collection_to_move_around_in_aproject']
527 visit page_with_token user, '/'
528 find("#projects-menu").click
529 find(".dropdown-menu a", text: my_project['name']).click
530 assert page.has_text?(my_collection['name']), 'Collection not found in project'
532 within('tr', text: my_collection['name']) do
533 find('input[type=checkbox]').click
536 click_button 'Selection'
537 within('.selection-action-container') do
538 click_link 'Create new collection with selected collections'
541 # now in the new collection page
542 if expect_collection_in_aproject
543 assert page.has_text?("Created new collection in the project #{my_project['name']}"),
544 'Not found flash message that new collection is created in aproject'
546 assert page.has_text?("Created new collection in your Home project"),
547 'Not found flash message that new collection is created in Home project'
549 assert page.has_text?('Content hash'), 'Not found content hash in collection page'
555 ["pipelines", "/pipeline_instances"],
556 ["collections", "/collections"]
557 ].each do |target,path|
558 test "Test dashboard button all #{target}" do
559 visit page_with_token 'active', '/'
560 click_link "All #{target}"
561 assert_equal path, current_path
565 def scroll_setup(project_name,
569 sort_parameters = nil)
570 project_uuid = api_fixture('groups')[project_name]['uuid']
571 visit page_with_token 'user1_with_load', '/projects/' + project_uuid
573 assert(page.has_text?("#{item_list_parameter.humanize} (#{total_nbr_items})"), "Number of #{item_list_parameter.humanize} did not match the input amount")
575 click_link item_list_parameter.humanize
579 find("th[data-sort-order='#{sort_parameters.gsub(/\s/,'')}']").click
584 def scroll_items_check(nbr_items,
590 for i in 1..nbr_items
591 items << "#{fixture_prefix}#{i}"
594 verify_items = items.dup
595 unexpected_items = []
597 within(".arv-project-#{item_list_parameter}") do
598 page.execute_script "window.scrollBy(0,999000)"
604 # Visit all rows. If not all expected items are found, retry
605 found_items = page.all(item_selector)
606 item_count = found_items.count
609 (0..item_count-1).each do |i|
610 # Found row text using the fixture string e.g. "Show Collection_#{n} "
611 item_name = found_items[i].text.split[1]
612 if !items.include? item_name
613 unexpected_items << item_name
615 verify_items.delete item_name
619 assert_operator( previous.downcase, :<=, item_name.downcase) if previous
624 assert_equal true, unexpected_items.empty?, "Found unexpected #{item_list_parameter.humanize} #{unexpected_items.inspect}"
625 assert_equal nbr_items, item_count, "Found different number of #{item_list_parameter.humanize}"
626 assert_equal true, verify_items.empty?, "Did not find all the #{item_list_parameter.humanize}"
631 ['project_with_10_collections', 10],
632 ['project_with_201_collections', 201], # two pages of data
633 ].each do |project_name, nbr_items|
634 test "scroll collections tab for #{project_name} with #{nbr_items} objects" do
635 item_list_parameter = "Data_collections"
636 scroll_setup project_name,
639 scroll_items_check nbr_items,
642 'tr[data-kind="arvados#collection"]'
647 ['project_with_10_collections', 10],
648 ['project_with_201_collections', 201], # two pages of data
649 ].each do |project_name, nbr_items|
650 test "scroll collections tab for #{project_name} with #{nbr_items} objects with ascending sort (case insensitive)" do
651 item_list_parameter = "Data_collections"
652 scroll_setup project_name,
657 scroll_items_check nbr_items,
660 'tr[data-kind="arvados#collection"]',
666 ['project_with_10_pipelines', 10, 0],
667 ['project_with_2_pipelines_and_60_jobs', 2, 60],
668 ['project_with_25_pipelines', 25, 0],
669 ].each do |project_name, num_pipelines, num_jobs|
670 test "scroll pipeline instances tab for #{project_name} with #{num_pipelines} pipelines and #{num_jobs} jobs" do
671 item_list_parameter = "Jobs_and_pipelines"
672 scroll_setup project_name,
673 num_pipelines + num_jobs,
675 # check the general scrolling and the pipelines
676 scroll_items_check num_pipelines,
679 'tr[data-kind="arvados#pipelineInstance"]'
680 # Check job count separately
681 jobs_found = page.all('tr[data-kind="arvados#job"]')
682 found_job_count = jobs_found.count
683 assert_equal num_jobs, found_job_count, 'Did not find expected number of jobs'
687 # Move button accessibility
690 ['active', true], # project owner
691 ['project_viewer', false],
692 ].each do |user, can_move|
693 test "#{user} can move subproject under another user's Home #{can_move}" do
694 project = api_fixture('groups')['aproject']
695 collection = api_fixture('collections')['collection_to_move_around_in_aproject']
697 # verify the project move button
698 visit page_with_token user, "/projects/#{project['uuid']}"
700 assert page.has_link? 'Move project...'
702 assert page.has_no_link? 'Move project...'
707 test "error while loading tab" do
708 original_arvados_v1_base = Rails.configuration.arvados_v1_base
710 visit page_with_token 'active', '/projects/' + api_fixture('groups')['aproject']['uuid']
712 # Point to a bad api server url to generate error
713 Rails.configuration.arvados_v1_base = "https://[100::f]:1/"
714 click_link 'Other objects'
715 within '#Other_objects' do
717 assert_selector('a', text: 'Reload tab')
719 # Now point back to the orig api server and reload tab
720 Rails.configuration.arvados_v1_base = original_arvados_v1_base
721 click_link 'Reload tab'
722 assert_no_selector('a', text: 'Reload tab')
723 assert_selector('button', text: 'Selection')
724 within '.selection-action-container' do
725 assert_selector 'tr[data-kind="arvados#trait"]'
730 test "add new project using projects dropdown" do
731 # verify that selection options are disabled on the project until an item is selected
732 visit page_with_token 'active', '/'
735 find("#projects-menu").click
736 click_link 'Add a new project'
737 assert_text 'New project'
738 assert_text 'No description provided'
740 # Add one more new project
741 find("#projects-menu").click
742 click_link 'Add a new project'
743 match = /New project \(\d\)/.match page.text
744 assert match, 'Expected project name not found'
745 assert_text 'No description provided'
748 test "first tab loads data when visiting other tab directly" do
749 # As of 2014-12-19, the first tab of project#show uses infinite scrolling.
750 # Make sure that it loads data even if we visit another tab directly.
751 need_selenium 'to land on specified tab using {url}#Advanced'
752 project = api_fixture("groups", "aproject")
753 visit(page_with_token("active_trustedclient",
754 "/projects/#{project['uuid']}#Advanced"))
755 assert_text("API response")
756 find("#page-wrapper .nav-tabs :first-child a").click
757 assert_text("bytes Collection")