Since version 2.0 introduced many breaking changes, we're upgrading to
it first.
The changes have been done by installing the rubocop-faker gem and
running:
```
rubocop \
--require rubocop-faker \
--only Faker/DeprecatedArguments \
--auto-correct
```
We introduced a bug in commit acbd1b023.
When editing a record and removing an existing image, we don't remove
the HTML fields associated with that image but simply hide them, and
then we add fields to create a new image when clicking on "Add image".
This is standard cocoon behavior. However, since in the case of images
there's a `has_one` relation, cocoon doesn't add unique identifiers to
the new fields, generating duplicate IDs, which is invalid HTML.
Since there's a duplicate file input ID, clicking on the "Choose image"
label we aren't clicking on the new input but on the old one. This means
we aren't correctly attaching an image. The tests passed because
Capybara uses the equivalent of a keyboard to select the field, and in
this case everything worked properly.
So we need to delete the existing elements before inserting new ones.
We're adding a test to check there aren't duplicate IDs.
We were hiding the file input and styling the label as a button instead.
Since clicking on a label has the same effect as clicking on the input,
the input worked properly for mouse and touch screen users.
However, hiding the input makes it inaccessible for keyboard users,
since labels don't get keyboard focus, but inputs do.
So we must not hide the input but make it invisible instead. But we
still need to hide the input (alongside the label) after a file has been
attached.
We could add some extra JavaScript to hide the input when we hide the
label. Since the JavaScript is already quite complex and my first few
attempts at changing it failed, I've opted to assume that the input (and
its label) must be hidden whenever there's already a file name, and
implement that rule with CSS.
Note we're using the `:focus-within` pseudoclass to style a label when
focus is on the input. This rule (at the time of writing) is only
supported by 93.5% of the browsers. Keyboard users without a screen
reader and using the other 6.5% of the browsers will still be able to
focus on the field but might not notice the field has received focus.
Since the percentage of affected users will decrease over time and until
now 100% of keyboard users were completely unable to focus on these
fields, for now we think this is a good-enough solution.
Using `dom_id` means generating `new_document` as ID for new documents.
Since there might be more than one new document in the form, that means
duplicate IDs, which is invalid HTML.
Even though this issue doesn't affect image fields (because we don't
have many images on the same form), we're removing the ID there as well
for consistency.
When we see a list of, let's say, banners, and each one has a link to
edit them, the word "banner" in the text "edit banner" is redundant and
adds noise; even for users with cognitive disabilities, it's obvious
that the "edit" link refers to the banner.
In commit 9794ffbbf, we replaced "buttons" with icons in order to make
the admin interface consistent with the planned budget investments
redesign.
However, using icons has some issues. For once, icons like a trash for
the "delete" action might be obvious, but other icons like "confirm
moderation" or "send pending" might be a bit confusing.
It's true that we were adding tooltips on hover. We tried two
approaches: using Foundation's tooltips and using CSS tooltips.
Foundation tooltips are not activated on focus (only on hover), while
CSS tooltips always appear below the icon, which might be a problem when
the icons are at the bottom of the screen (one of our milestone tests
was failing because of that and we can now run it with JavaScript
enabled).
Both Foundation and CSS tooltips have other issues:
* They force users to make an extra step and move the mouse over the
link just to know what the link is about
* They aren't available on touch screens, so these users will have to
memorize what each icon does
* They are not hoverable, and making them hoverable would cause a
different issue because the tooltip might cover links below it, making
it impossible to click these links without moving the mouse away
first
* They are not dismissable, which is considered an accessibility issue
and a requirement in the Web Content Accessibility Guidelines [1]
For all these reasons, we're using both texts and icons. As Thomas
Byttebier said "The best icon is a text label [2]". Heydon Pickering
also makes a point towards providing text alongside icons in his book
"Inclusive Components" [3].
Note that, since we're now adding text and some of the colors we use for
actions are hard to read against a white/gray background, we're making a
few colors darker.
With these changes, actions take more space in the admin table compared
to the space they took in version 1.3, but they are more usable and
accessible while they still take less space than they did in version
1.2.
[1] https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus
[2] https://thomasbyttebier.be/blog/the-best-icon-is-a-text-label
[3] https://inclusive-components.design/tooltips-toggletips/
It looks like this bug was introduced in commit 7ca55c4. Before that
commit, a message saying "You added a new related content" was shown,
but (as expected) the related content wasn't added twice.
We now check this case and add a slightly clearer message.
Some CONSUL installations might want to customize their URLs. For
instance, Spanish institutions might want to use "/propuestas" instead
of "/proposals". In that case, it would be impossible to add proposals
as related content because the related contents controller assumed the
name of the model was part of the URL.
Using `recognize_path` instead of manually analyzing the URL solves the
issue.
Now that we don't call the `constantize` method on an empty string as we
previously did, we can be more specific in the `rescue` block and point
out that the only exception we expect is the one where users enter a
route which isn't recognized.
We were only showing these actions to users with small screens and to
mouse users on hover. Keyboard users or users with a touch screen of a
medium or large size could never find out the actions were there.
It didn't have a `for` attribute and so it wasn't correctly associated
with its input. That means clicking on / touching the label didn't have
the effect of focusing on the field, and screen readers wouldn't
announce the label.
The button was announced as expanded when the form was hidden and as
collapsed when the form was shown.
This is because Foundation sets the expanded attribute based on whether
the class to toggle already exists. Since initially the form had the
"hide" class and the button toggled that class, Foundation checked that
the class was already present and so set the button as expanded.
So we're changing the toggler class for a class we don't use at all,
just so Foundation initiall sets `aria-expanded=false` and then changes
it to `aria-expanded=true` after the button is clicked. Then we're
ignoring this class completely and are styling this form with CSS
instead.
We could also use a toggler class like "visible" and write something
like:
```
.add-related-content + form:not(.visible) {
display: none;
}
```
However, using ARIA attributes is more robust as it guarantees the
styles will always be in sync with what screen reader users experience.
And we could also remove all the Foundation toggler functionality and
use our own JavaScript to handle the button state. We might do so in the
future.
We're removing the parenthesis after page expectations (as we do almost
everywhere) and we're replacing `have_selector` with `have_css`, since
on that file we were using `have_css` everywhere except in one place.
A button cannot be inside an anchor tag, and it might confuse some
browsers or screen readers.
We're also making it clear in the tests that the intention is to use a
button there by using `click_button` instead of `click_on` since the
latter also clicks on links.
In the Management section when creating an investment we were not passing the
document attributes, so we were never able to associate documents.
Make the nested_documentable spec compatible with the Management section.
In the Management section when creating an investment we were not passing the
images attributes, so we were never able to associate images.
Make the nested_imageable spec compatible with the Management section.
That way we make sure the request is finished before the test finishes.
We were getting a failure in GitHub Actions because an unrelated test
executed after this one had its locale set to Spanish (just for one
test, though), and one possible explanation could be that a previous
request which changed I18n.locale was still being executed.
We've got quite a messy hack to sign in managers: they need to visit a
specific URL (management root path).
That means tests signing in managers start the browser to sign them in,
which might cause issues if we setup the database after that.
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.
There's a usability issue in certain cases in browsers: when the
milestones table is at the bottom of the screen and it fills the screen
width completely, hovering over the link to delete a milestone makes the
"Delete milestone" tooltip cause a horizontal scrollbar. The scrollbar
makes it impossible for users to click the link.
We should probably fix this usuability issue; for now, I'm keeping the
test the way it was.
Using `<a>` tags with no `href` means these elements cannot be activated
by keyboard users, so we're replacing them with buttons.
In the future we probably want to add more consistency so all toggle
buttons use the same code. We might also add styles depending on the
`aria-expanded` property.
We were displaying the total number of notifications with a message "You
have N unread notifications", but were using the total number of
notifications instead of the unread ones.
Other than simplifying the view, we can write tests using `click_link`,
which makes the tests more robust. Clicking the `.icon-notification`
element was causing some tests to fail when defining a window height of
750 pixels in the `admin_budgets` branch.
We had one exception running test suite [1]:
```
1) Commenting legislation questions Merged comment threads View
comments of annotations in an included range
Failure/Error: count: annotation.comments.roots.count) %>
ActionView::Template::Error:
PG::ProtocolViolation: ERROR: bind message supplies 0
parameters, but prepared statement "" requires 2
: SELECT COUNT(*) FROM "comments" WHERE "comments"."hidden_at" IS
NULL AND "comments"."commentable_id" = $1 AND
"comments"."commentable_type" = $2 AND "comments"."ancestry" IS NULL
```
Debugging shows this test was run right after the flaggable specs.
There's a chance these exceptions take place because the test is
accessing the database after the browser (chromedriver) process has
already accessed the database.
This is just an attempt at fixing the issue; I don't know whether these
changes will fix it since I've only seen this exception on Github
Actions (never on my machine). Worst case scenario, we're encouraging
good practices of system tests: test things from the user's point of
view.
[1] https://github.com/consul/consul/runs/1856245992
So tests won't fail when an institution changes the default organization
name.
The tests are also easier to understand now, since it's more obvious
where the "CONSUL" text is coming from.
We were repeating the same code over and over (with a few variants) to
setup tests which require an administrator. We can use a tag and
simplify the code.
In some tables, we had "actions", and some columns were also links
pointing to some places. Having both of them at the same time is
confusing, particularly since traditionally the links in the columns
pointed to the same place as some of the actions (although that's not
the case since commit 48db31cd).
We're still keeping links in tables which don't have an action column.
For instance, the proposals table has a "select" button which would be
harder to use if we had action buttons next to it.
This rule was added in rubocop-rspec 1.39.0. The `visible: false` option
is equivalent to `visible: :all`, but we generally use it meaning
`visible: :hidden` for positive expectations and `visible: :all` for
negative expectations.
The only exceptations are tests where we count the number of map icons
present. I'm assuming in this case we care about the number of map icons
independently on whether they are currently shown in the map, so I'm
keeping the `visible: :all` behavior in this case.
By default, Capybara only finds visible elements, so adding the
`visible: true` option is usually redundant.
We were using it sometimes to make it an obvious contrast with another
test using `visible: false`. However, from the user's perspective, we
don't care whether the element has been removed from the DOM or has been
hidden, so we can just test that the visible selector can't be found.
Besides, using `visible: false` means the test will also pass if the
element is present and visible. However, we want the test to fail if the
element is visible. That's why a couple of JavaScript-dependant tests
were passing even when JavaScript was disabled.
This rule was added in Rubocop 0.91.0. A similar rule named
LeakyConstantDeclaration was added in rubocop-rspec 1.34.0.
Note using the FILENAMES constant did not result in an offense using the
ConstantDefinitionInBlock rule but did result in an offense using the
LeakyConstantDeclaration rule. I've simplified the code to get rid of
the constant; not sure why we were adding a constant with `||=` in the
middle of a spec.
When a user recovers a page from browser history where placed a
marker in different map pane (visible map layer) marker was
successfully added to the map but the map center is the one
defined at Settings map properties so the marker was not visible
to the user.
Now when map_location form has valid coordinates we use them
instead of default map center settings. This will avoid the user to
have to rellocate the marker (or find the correct pane where the
marker was added) if already placed.
When using an editable map is better to load marker latitude, longitude and
map zoom from form fields so we can show the marker at latest position defined
by user when the page was restored from browser history.
To reproduce this behavior:
0. Undo this commit
1. Go to new proposal page
2. Place the proposal map marker
3. Go away to any other page
4. Restore new proposal page from browser history.
At this point you should not see the recently placed marker.
The same thing happens when editing a proposal.
If we do not do this a map could be initialized twice times or more
when restoring a page with a map causing weird UI effects and
loading some map layers also twice times or more.
Need to add a maps array to be able to store all initialized
(visible) maps so we can destroy them when needed. Notice that
we are destroying maps also when admin settings tabs changes
(only visible ones), this is again to avoid to re-initialize map more
than once when users navigate through settings tabs, another
option to the settings issue could be to detect if the map was
already initialized to skip uneeded initialization.