After a `visit`, we were checking for content or filling in fields that
were already there before the `visit`, so we weren't 100% sure that the
request had finished before the test continued.
In the case of the verification tests, we were clicking the submit
buttons over and over without and then checking or interacting with
elements that were already there. Even though the button was disabled
between requests, meaning there wouldn't be simultaneous requests, it
was possible to interact with a form field before waiting for the
request to finish.
Some of these tests have recently failed on our CI, and it might be
because of that:
```
1) Admin budgets Edit Changing name for current locale will update the
slug if budget is in draft phase
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
1) Budgets creation wizard Creation of a multiple-headings budget by
steps
Failure/Error: expect(page).to have_content "Heading created
successfully!"
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
1) Custom information texts Show custom texts instead of default ones
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
1) Users Regular authentication Sign in Avoid username-email collisions
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
2) Verify Letter Code verification 6 tries allowed
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
2) Valuation budget investments Valuate Finish valuation
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
1) Users Delete a level 2 user account from document verification page
Failure/Error: raise ex, cause: cause
Selenium::WebDriver::Error::UnknownError:
unknown error: unhandled inspector error: {"code":-32000,
"message":"Node with given id does not belong to the document"}
(Session info: chrome=134.0.6998.35)
```
This way it's more obvious what's going on.
Note that, in this case, the expectations were **not** true before
visiting the page, so we aren't fixing a flaky test.
This way it'll be easier for people using screen readers to know which
element the checkbox is related to.
Note that we're using the `aria-label` attribute because it makes
testing with Capybara easier than using the `aria-labelledby` attribute.
The only exception are the comments, since comments don't have a title
and there isn't a proper label for them. In this case, we're using the
title of the associated commentable as the label; we might change it in
the future since there might be many comments for the same commentable.
Since they're related, we're making them part of the same list. Instead
of finding a way to have the `Select` prefix they had as a label for the
list, we're including the "prefix" they had inside their texts, so the
text of a button doesn't need any additional context.
People using screen readers usually expect links to take them somewhere
else in the page on to a different page, while they expect buttons to
change something on the page.
Since we're in the latter scenario, using a button is more accessible.
It's also more natural; with a button, we don't need to provide `#` as
the URL or stop the default event when the button is clicked. And,
unlike links, buttons can be activated with either the space or the
enter key. Finally, clicking a link pointing to `#` with the middle
mouse button opens a useless new tab, while buttons do nothing in this
case.
Now that we only have one "All" link on the page, we no longer need to
specify which "All" link we're clicking or which "All" link we are
checking, so we're simplifying the code doing so.
Since we don't usually style HTML classes starting with `js-`, we're
renaming it, so it's consistent with the `CheckAllNone` name used in the
`check_all_none.js` file.
Since we were on the "Pending review" filter, and there were no records
pending review, the code checking all checkboxes were checked/unchecked
didn't test anything because there were no checkboxes on the page.
So we're clicking on the "All" filter first.
Note we're excluding a few files:
* Configuration files that weren't generated by us
* Migration files that weren't generated by us
* The Gemfile, since it includes an important comment that must be on
the same line as the gem declaration
* The Budget::Stats class, since the heading statistics are a mess and
having shorter lines would require a lot of refactoring
We were clicking on the "Sign in" link right after clicking on the "Sign
out" link, which might result in simultaneous requests and exceptions
when running our test suite.
So we're adding an expectation to make sure the first request has
finished before starting the following one.
After a user assigned as a budget admin deletes their account or gets blocked by
a moderator, the application throws an exception while loading the admin
investment index page.
As an erased user is not really deleted and neither its associated roles, the
application was failing when trying to sort and administration without a
username. In this case, the application was throwing an `ArgumentError:
comparison of NilClass with String failed` exception.
As a blocked user is not deleted or its roles, the application failed when trying
to access the user name through the delegation in the Administrator. In this
case, the application was throwing a `NoMethodError: undefined method `name' for
nil:NilClass` exception.
It was a bit confusing to press the "hide" button and then see the user
listed as "blocked". Some moderators might think they accidentally
pressed the wrong button.
In the moderation section there's no clear indicator as to what the
"Hide" and "Block" buttons do and the difference between them.
Since we're using confirmation dialogs in all moderation actions except
these ones, we're adding them here as well, so the difference will
appear in the dialog.
This isn't a very good solution, though, since the confirmation dialog
comes after clicking the button and users have already been wondering
whether clicking that button will be the right choice. A better solution
would be making the purpose clear before the button is clicked, although
that's something we don't do anywhere in the admin/moderation sections.
We're continuing to replace links with buttons, for the reasons
explained in commit 5311daadf.
Since we're using the admin action component, we can also simplify the
logic handling the confirmation message.
In order to avoid duplicate IDs when generating buttons to block the
same author more than once in a page, we're including the record dom_id
in the ID of the button to block an author.
The `hide` action was calling the `block` method while the `soft_block`
action was calling the `hide` method.
Combined with the fact that we also have a `block` permission which is
used in `ModerateActions` the logic was hard to follow.
Other than removing a redundant action, we're fixing two bugs when
blocking an author using the links in the public views:
* We were always redirecting to the debates index, even if we blocked
the author of a proposal or an investment
* We weren't showing any kind of success message
We're continuing to replace links with buttons, for the reasons
explained in commit 5311daadf.
We're also adding an ARIA label since on the same page there might be
several links to block different users.
Using order links in this case causes an unusual interface, where we
show filter links, then information about the number of results, and
then order links.
Whether or not this makes sense needs to be confirmed with usability
tests. In any case, this is still way better than using `<select>`
fields which automatically change to a new page, since they cause
problems to keyboard users, are harder to select for touchscreen users,
might confuse screen reader users who will notice a form but no way to
submit it, and are not elements we generally use to let users choose the
order of the records.
For a more detailed explanation of these issues, check the commit
message in the commit "Use order links to sort comments and topics"
(just a few commits ago).
We were checking what happens in the database, but what's important is
what users experience after hiding content or blocking authors. Besides,
accessing the database in tests after the browser has started might lead
to database inconsistencies.
Just like we mentioned in commit 5f0c422eb, the filter "Mark as viewed"
doesn't work properly, so here's a case where the test would fail with
JavaScript not because the test is wrong, but due to a bug. The test was
passing simplify because there was a typo in the CSS selector, which was
supposed to select an element by ID but didn't have the "#" prefix.
For now we're keeping the test as it was, but eventually we'll have to
fix the bug.
JavaScript is used by about 98% of web users, so by testing without it
enabled, we're only testing that the application works for a very
reduced number of users.
We proceeded this way in the past because CONSUL started using Rails 4.2
and truncating the database between JavaScript tests with database
cleaner, which made these tests terribly slow.
When we upgraded to Rails 5.1 and introduced system tests, we started
using database transactions in JavaScript tests, making these tests much
faster. So now we can use JavaScript tests everywhere without critically
slowing down our test suite.
The filter "Mark as viewed" doesn't work properly, so here's a case
where the test would fail with JavaScript not because the test is wrong,
but due to a bug.
For now we're keeping the test as it was, but eventually we'll have to
fix the bug.
Using `have_current_path`, Capybara waits until the condition is true,
while using `include` the expectation is evaluated immediately and so
tests might fail when using a driver supporting JavaScript.
Besides, using `have_current_path` the error message is more readable
when the test fails.
System tests are used to test the application from the user's point of
view. To test for specific exceptions, particularly regarding
authorization permissions, controller tests fit better.
Another option would be to test the page displayed shows a certain text,
like "Internal server error". I'm choosing controller tests because
they're faster and we're basically testing the same scenario many times
and we've already got a test checking what happens when users access a
page raising an exception.