Commit Graph

21 Commits

Author SHA1 Message Date
Javi Martín
999d5c2f67 Remove redundant "Manage" in admin menu entries
This is the admin section; it's obvious that every link in the menu will
take you to a page to manage something.

We're going to add a new item to either the "Settings" or the "Site
content" section, so it's a good time to improve what's already there.
2024-06-05 16:10:56 +02:00
Javi Martín
db25dc13e1 Use buttons to open/close admin navigation submenus
We were using Foundation's accordion menu to open/close nested lists of
links. Unfortunately, Foundation's accordion makes it impossible to
access links in nested links using the keyboard [1] (note the issue is
closed, but in the latest version of Foundation, 6.8.1, it's still
present, and Foundation's development is mostly discontinued).
Furtheremore, it adds the `menuitem` role to links, but ARIA menus are
not ment for navigation but for application behavior and, since it
doesn't add the `menubar` or `menu` roles to the parent elements, it
results in accessibility issues for people using screen readers (also
reported by the Axe accessibility testing engine).

So we need to implement our own solution. We're using the most commonly
used pattern: a buttton with the `aria-expanded` attribute. And, for
people using browsers where JavaScript hasn't loaded, we're keeping the
submenus open at all times (just like we were doing until now), and
we're disabling the buttons (since they do nothing without JavaScript).
This might not be an ideal solution, but it's probably good enough, and
way better than what we had until now.

We've also considered using the <details> and <summary> elements instead
of using buttons to open/close items on the list. However, these
elements still present some accessibility issues [2], and the transition
between open and closed can't be animated unless we overwrite the
`click` event with JavaScript. The pattern of using these elements to
open/close a nested list of links isn't common either, and some people
using screen readers might get confused when entering/leaving the nested
list.

We tried other approaches to get the animation effect, all of them based
on adding `[aria-expanded="false"]:not([disabled]) + * { display: none;
}` to the CSS file.

Unfortunately, animation using CSS isn't feasible right now because
browsers can't animate a change form `height: 0` to `height: auto`.
There are some hacks like animating the `max-height` or the `flex-grow`
property, but the resulting animation is inconsistent. A perfect
animation can be done using the `grid-template-rows` property [3], but
it requires adding a grid container and only works in Firefox and recent
versions of Chrome and similar browsers.

Getting to a solution with JavaScript was also tricky. With the
following approach, `slideToggle()` opened the menu the first time, even
if it was already open (not sure why):

```
toggle_buttons.on("click", function() {
  $(this).attr("aria-expanded", !JSON.parse($(this).attr("aria-expanded")));
  $(this).next().slideToggle();
});
```

This made the arrow turn after the menu had slided instead of doing it
at the same time:

```
toggle_buttons.on("click", function() {
  var button = $(this);

  button.next().slideToggle(function() {
    button.attr("aria-expanded",
    !JSON.parse(button.attr("aria-expanded")));
  });
}
```

With this, everything disappeared quickly:

```
toggle_buttons.on("click", function() {
  var expanded = JSON.parse($(this).attr("aria-expanded"));

  if (expanded) {
    $(this).next().slideUp();
  } else {
    $(this).next().slideDown();
  }

  $(this).attr("aria-expanded", !expanded);
}
```

So, in the end, we're hiding the nested link lists with JavaScript
instead of CSS.

[1] Issue 12046 in https://github.com/foundation/foundation-sites
[2] https://www.scottohara.me/blog/2022/09/12/details-summary.html
[3] https://css-tricks.com/css-grid-can-do-auto-height-transitions
2024-04-18 16:10:58 +02:00
Javi Martín
0cec581ec0 Add and apply Capybara/RSpec/HaveSelector rule
This rule was added in rubocop-capybara 2.19.0. We were following it
about 85% of the time.

Now we won't have to check both have_css and have_selector when
searching the code.
2023-11-08 14:18:16 +01:00
Javi Martín
8b13daad95 Add and apply rules for multi-line hashes
For the HashAlignment rule, we're using the default `key` style (keys
are aligned and values aren't) instead of the `table` style (both keys
and values are aligned) because, even if we used both in the
application, we used the `key` style a lot more. Furthermore, the
`table` style looks strange in places where there are both very long and
very short keys and sometimes we weren't even consistent with the
`table` style, aligning some keys without aligning other keys.

Ideally we could align hashes to "either key or table", so developers
can decide whether keeping the symmetry of the code is worth it in a
case-per-case basis, but Rubocop doesn't allow this option.
2023-08-18 14:56:16 +02:00
Javi Martín
d4c62e2fc6 Add notice after destroying a banner
We were missing a notice in this case. Not only this caused
inconsistencies in the user experience, but it also made it hard to add
an expectation in the test checking the request had finished before
making a new one. Simultaneous requests sometimes cause failures in our
test suite.
2022-06-02 19:05:02 +02:00
rhian-cs
609e58cacb Update system specs with detailed confirmation alerts 2021-12-22 12:32:47 +01:00
Javi Martín
5311daadfe Use a button for non-GET table actions
Links acting like buttons have a few disadvantages.

First, screen readers will announce them as "links". Screen reader users
usually associate links with "things that get you somewhere" and buttons
with "things that perform an action". So when something like "Delete,
link" is announced, they'll probably think this is a link which will
take them to another page where they can delete a record.

Furthermore, the URL of the link for the "destroy" action might be the
same as the URL for the "show" action (only one is accessed with a
DELETE request and the other one with a GET request). That means screen
readers could announce the link like "Delete, visited link", which is
very confusing.

They also won't work when opening links in a new tab, since opening
links in a new tab always results in a GET request to the URL the link
points to.

Finally, submit buttons work without JavaScript enabled, so they'll work
even if the JavaScript in the page hasn't loaded (for whatever reason).

For all these reasons (and probably many more), using a button to send
forms is IMHO superior to using links.

There's one disadvantage, though. Using `button_to` we create a <form>
tag, which means we'll generate invalid HTML if the table is inside
another form. If we run into this issue, we need to use `button_tag`
with a `form` attribute and then generate a form somewhere else inside
the HTML (with `content_for`).

Note we're using `button_to` with a block so it generates a <button>
tag. Using it in a different way the text would result in an <input />
tag, and input elements can't have pseudocontent added via CSS.

The following code could be a starting point to use the `button_tag`
with a `form` attribute. One advantage of this approach is screen
readers wouldn't announce "leaving form" while navigating through these
buttons. However, it doesn't work in Internet Explorer.

```
ERB:

<% content_for(:hidden_content, form_tag(path, form_options) {}) %>
<%= button_tag text, button_options %>

Ruby:

def form_id
  path.gsub("/", "_")
end

def form_options
  { id: form_id, method: options[:method] }
end

def button_options
  html_options.except(:method).merge(form: form_id)
end

Layout:

<%= content_for :hidden_content %> # Right before the `</body>`
```
2021-09-20 20:27:37 +02:00
Javi Martín
7d590031f5 Remove redundant words in edit and destroy links
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.
2021-06-30 14:33:37 +02:00
taitus
85611a5103 Adding consistency for post_started_at and post_ended_at on specs
These two fields are of type Date and in some specs they are being
filled as Time or DateTime.
2021-04-08 17:23:33 +02:00
Javi Martín
92ddcb7aef Use JavaScript in system tests by default
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.
2021-04-07 14:41:06 +02:00
Javi Martín
222e4c9542 Use JavaScript in tests using the admin menu
This menu requires JavaScript to open/close subnavigation menus, so
we're now testing the way users with a browser supporting JavaScript
(98%-99% of the users) deal with the menu.
2021-04-07 14:41:06 +02:00
Javi Martín
e3deff8bdc Remove redundant banners test
We're implicitly checking the link is listed on the menu by clicking it
in other tests.
2021-04-07 14:41:06 +02:00
Javi Martín
b2bc4d19f5 Use JavaScript in tests opening modal dialogs
This way we reproduce the user experience in the tests, and we can make
sure modal dialogs open when we expect it.
2021-04-07 14:41:06 +02:00
Javi Martín
2036b3d44e Add success message when creating/updating banners 2021-04-07 14:35:30 +02:00
Javi Martín
f3595833fd Improve readability in some system specs
We're improving the readability of the ones we're about to modify.
Using human texts makes tests easier to read and guarantees we're
testing from the user's point of view. For instance, if we write
`fill_in banner_target_url`, the test will pass even if the field has no
label associated to it. However, `fill_in "Link"` makes sure there's a
field with an associated label.
2021-04-07 14:32:49 +02:00
Javi Martín
0c95ababdf Use dates to fill in admin date input fields
Tests are easier to read now. Besides, since we changed the inputs in
the admin section so they don't use jQuery but an HTML date field,
formatting with %d/%m/%Y might not work depending on the browser's
locale.
2021-03-31 14:09:13 +02:00
Javi Martín
3da4ee00b8 Simplify tests requiring admin login
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.
2020-12-02 15:33:19 +01:00
Senén Rodero Rodríguez
a543fa7ea2 Use labels for banner web_section_ids checkboxes so text its clickable
Now we can use the checkbox label text directly as locator at spec,
also default web_sections are created before every spec by loading
`db/seeds.rb` file so we were duplicating "Proposals" WebSection.
2020-10-28 16:42:56 +01:00
Javi Martín
fc9a87a8ab Use native HTML5 date fields in the admin section
We've had to add a couple of hacks in order to make jQuery UI datepicker
work with Turbolinks, and one of our tests is failing because the
datepicker changes its height when changing from a month with 5 weeks to
a month with 6 weeks.

We could add a workaround so the test still passes (jQuery UI doesn't
provide a configuration option to always displays 6 weeks in the
datepicker), but I think it's easier to just use the HTML5 native date
input field, which also allows us to simplify the code a bit and IMHO it
improves the user experience, particularly when using mobile phones.

Since date fields are not supported in Safari and Internet Explorer,
we're still using the jQuery UI datepicker on those browsers (and on any
other browser not supporting date fields).

Due to these changes, we're moving the tests checking datepicker's
behaviour to the dashboard. I've choosing not to change the public pages
because I'm not 100% sure everybody would like this change (some people
prefer the datepicker because we can configure the way it looks).
2020-08-28 12:55:58 +02:00
Senén Rodero Rodríguez
da658f3d8c Hack datepicker to make it work with Turbolinks 5.x
Patch extracted from here the comments on turbolinks issue 253 and
converted to vanilla javascript.

The hide action over datepickers ensures us that opened datepickers
will be closed before leving the page. Previously if you open any
datepicker and then move to previous page you will keep seeing the
datepicker in the restored page.
2020-08-12 10:07:35 +02:00
Javi Martín
9427f01442 Use system specs instead of feature specs
We get rid of database cleaner, and JavaScript tests are faster because
between tests we now rollback transactions instead of truncating the
database.
2020-04-24 15:43:54 +02:00