简体   繁体   中英

Rails rspec capybara selector not found

I have this integration test using capybara:

RSpec.describe 'adding a project', type: :system do
  it 'allows a user to create a project with a tasks' do
    visit new_project_path
    fill_in 'Name', with: 'Project Runaway'
    fill_in 'Tasks', with: 'Choose Fabric:3\nMake it Work:5'
    click_on('Create a project')
    visit projects_path
    @project = Project.find_by(name: "Project Runaway")
    expect(page).to have_selector(
      "#project_#{@project.id} > td.name", text: "Project Runaway"
    )
    expect(page).to have_selector(
      "#project_#{@project.id} > td.total-size", text: "8"
    )
  end
end

Somehow it can't find the last selector (td.total-size):

Failures:

  1) adding a project allows a user to create a project with a tasks
     Failure/Error:
       expect(page).to have_selector(
         "#project_#{@project.id} > td.total-size", text: "8"
       )

       expected to find visible css "#project_1 > td.total-size" with text "8" but there were no matches. Also found "3", which matched the selector but not all filters.



     # ./spec/system/add_project_spec.rb:14:in `block (2 levels) in <main>'

But the test is passed when I comment the last assertion. But failed if I commented the td.name part and left the td.total-size uncommented.

Here is the HTML page:

<h1>All Projects</h1>
<table>
  <thead>
    <tr>
      <td>Project Name</td>
      <td>Total Project Size</td>
    </tr>
  </thead>
  <tbody>
    <% @projects.each do |project| %>
    <tr class="project-row", id="<%= dom_id(project) %>">
      <td class="name"><%= project.name %></td>
      <td class="total-size"><%= project.total_size %></td>
    </tr>
    <% end %>
  </tbody>
</table>

I need to make sure all the data displayed on the table is right. Anyone has the same experience?

For additional information, I am using:

  • Rails 5.2.1
  • Ruby 2.5.0
  • Rspec 3.7.1
  • Capybara 3.11.1

Thanks in advance

Updated

<body>
    <h1>All Projects</h1>
    <table>
      <thead>
        <tr>
          <td>Project Name</td>
          <td>Total Project Size</td>
        </tr>
      </thead>
      <tbody>
        <tr class="project-row", id="project_1">
          <td class="name">Project Runaway</td>
          <td class="total-size">8</td>
        </tr>
      </tbody>
    </table>
  </body>

This is what the html rendered.

The error is telling you that the element you expect to have text content of "8" has text content of "3". That would imply to me that either your app has a bug or that fill_in 'Tasks', with: 'Choose Fabric:3\\nMake it Work:5' isn't doing what you expect it to. Pause the test and look at the browser to see what's actually being created and/or look at your test.log to see what is being submitted and what elements are actually being created. Note also that I would expect your test to be pretty flaky because you're not actually waiting for whatever action(s) click_on('Create a project') performs. That means the following visit can occur before those actions occur and end up cancelling them. Add an assertion between the click and visit for whatever visual change indicates the project creation has completed

click_on('Create a project')
expect(page).to have_text('Project created!') # whatever your app does to indicate successful creation
visit projects_path

You can use element hierarchy for table and its td and tr. such as

#getting text of 1st cell of 2nd row
name = find('#tableId tbody tr:nth-of-type(2) td:nth-of-type(1)').text
if name == "Project Name"
   # do what ever you want to do
else
   # do what ever you want to do
end

you can put above code block in while loop to go through each and every cell of table. Note: Capybara counter starts with 1 so tr:nth-of-type(2) simply means 2nd row.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM