I'm testing this piece of Rails HTML code and its click function:

<tr>
    <td class="arrow-uped" id="tupa" onclick="send_vote()">
    </td>
    <td rowspan="3" class="restname"> Chipotle
    </td>
</tr>

<tr>
    <td class="votenumber"><%= vote_count %>
    </td>
</tr>

<tr>
    <td class="arrow-down" id="tdpa" onclick="send_vote()">
    </td>
</tr>

To click the element, you could do either

find("#tupa").click

or

page.all('#tupa')[0].click

Once it's clicked, it triggers an ajax call to update the vote counts in database. When the call returns, it updates the vote count on the page accordingly as well. The test reads the actual vote count on the page, and compare with expected value. You have options of doing

assert_equal find(".votenumber").text, "1"

or

votes = page.all('.votenumber').map(&:text)
assert_equal votes,['1']

But if you do this:

votes = page.execute_script("$('td.votenumber').html()")
assert_equal votes,['1'] 

You will get error message:

Expected: nil
Actual: ["1"]

To validate the JQuery script, I manually ran the script at console.

>>$('td.votenumber').html()
>>"
          1
        "

So it does return text string 1. Then why the return value from test is nil?

Let's read Capybara Session#execute_script docs:

(Object) execute_script(script)

Execute the given script, not returning a result. This is useful for
scripts that return complex objects, such as jQuery statements.
execute_script should be used over evaluate_script
whenever possible.

That's why! Capybara is designed to return nil for execute_script not to return a value.

Alternatively, there's evaluate_script call defined as:

(Object) evaluate_script(script)

Evaluate the given JavaScript and return the result. Be careful when using
this with scripts that return complex objects, such as jQuery statements.
execute_script might be a better alternative.

So here we should instead use

votes = page.evaluate_script("$('td.votenumber').html()").to_i
assert_equal votes, 1 

Then it's all good!