discourse/spec/system/header_spec.rb
David Taylor 66de6a43a8
FIX: Ensure do-not-disturb icon updates correctly (#28253)
`currentUser.do_not_disturb_until` is a string, so we need to parse it before comparing to the current timestamp
2024-08-06 19:13:13 +01:00

320 lines
11 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# frozen_string_literal: true
RSpec.describe "Glimmer Header", type: :system do
let(:header) { PageObjects::Pages::Header.new }
let(:search) { PageObjects::Pages::Search.new }
fab!(:current_user) { Fabricate(:user) }
fab!(:topic)
before { SiteSetting.glimmer_header_mode = "enabled" }
it "renders basics" do
visit "/"
expect(page).to have_css("header.d-header")
expect(page).to have_css("#site-logo")
end
it "displays sign up / login buttons" do
visit "/"
expect(page).to have_css("button.sign-up-button")
expect(page).to have_css("button.login-button")
find("button.sign-up-button").click
expect(page).to have_css(".d-modal.create-account")
header.click_outside
find("button.login-button").click
expect(page).to have_css(".d-modal.login-modal")
end
it "shows login button when login required" do
SiteSetting.login_required = true
visit "/"
expect(page).to have_css("button.login-button")
expect(page).to have_css("button.sign-up-button")
expect(page).not_to have_css("#search-button")
expect(page).not_to have_css("button.btn-sidebar-toggle")
end
it "renders unread notifications count when user's notifications count is updated" do
Fabricate(
:notification,
user: current_user,
high_priority: true,
read: false,
created_at: 8.minutes.ago,
)
sign_in(current_user)
visit "/"
expect(page).to have_selector(
".header-dropdown-toggle.current-user .unread-notifications",
text: "1",
)
end
it "doesn't show pending reviewables count for non-legacy navigation menu" do
SiteSetting.navigation_menu = "sidebar"
current_user.update!(admin: true)
Fabricate(:reviewable)
sign_in(current_user)
visit "/"
expect(page).not_to have_selector(".hamburger-dropdown .badge-notification")
end
it "closes revamped menu when clicking outside" do
sign_in(current_user)
visit "/"
find(".header-dropdown-toggle.current-user").click
expect(page).to have_selector(".user-menu.revamped")
find("header.d-header").click
expect(page).not_to have_selector(".user-menu.revamped")
end
it "closes menu-panel when keyboard focus leaves it" do
sign_in(current_user)
visit "/"
find(".header-dropdown-toggle.current-user").click
find("##{header.active_element_id}").send_keys(%i[shift tab])
expect(page).not_to have_selector(".user-menu.revamped")
end
it "automatically focuses the first link in the hamburger panel" do
SiteSetting.navigation_menu = "header dropdown"
visit "/"
find("#toggle-hamburger-menu").click
expect(page).to have_selector(".panel-body")
first_link = find(".panel-body a", match: :first)
first_link_href = first_link[:href]
focused_element_href = evaluate_script("document.activeElement.href")
expect(focused_element_href).to eq(first_link_href)
end
it "sets header's height css property" do
sign_in(current_user)
visit "/"
header.resize_element(".d-header", 90)
wait_for(timeout: 100) do
header.get_computed_style_value(".d-header", "--header-offset") == "90px"
end
expect(header.get_computed_style_value(".d-header", "--header-offset")).to eq("90px")
header.resize_element(".d-header", 60)
wait_for(timeout: 100) do
header.get_computed_style_value(".d-header", "--header-offset") == "60px"
end
expect(header.get_computed_style_value(".d-header", "--header-offset")).to eq("60px")
end
it "body document is permanently docked regardless of scroll positioning" do
Fabricate.times(20, :topic)
sign_in(current_user)
visit "/"
expect(page).to have_selector("body.docked")
page.execute_script("window.scrollBy(0, 1000)")
expect(page).to have_selector("body.docked")
page.execute_script("window.scrollTo(0, 0)")
expect(page).to have_selector("body.docked")
end
it "moves focus between tabs using arrow keys" do
sign_in(current_user)
visit "/"
find(".header-dropdown-toggle.current-user").click
expect(header.active_element_id).to eq("user-menu-button-all-notifications")
find("##{header.active_element_id}").send_keys(:arrow_down)
expect(header.active_element_id).to eq("user-menu-button-replies")
4.times { find("##{header.active_element_id}").send_keys(:arrow_down) }
expect(header.active_element_id).to eq("user-menu-button-profile")
find("##{header.active_element_id}").send_keys(:arrow_down)
expect(header.active_element_id).to eq("user-menu-button-all-notifications")
find("##{header.active_element_id}").send_keys(:arrow_up)
expect(header.active_element_id).to eq("user-menu-button-profile")
end
it "prioritizes new personal messages bubble over unseen reviewables and regular notifications bubbles" do
Fabricate(:private_message_notification, user: current_user)
Fabricate(
:notification,
user: current_user,
high_priority: true,
read: false,
created_at: 8.minutes.ago,
)
sign_in(current_user)
visit "/"
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.unread-notifications",
)
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-reviewables",
)
expect(page).to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-pms",
)
expect(page).to have_css(".d-icon-envelope")
expect(
find(".header-dropdown-toggle.current-user .badge-notification.with-icon.new-pms")[:title],
).to eq(I18n.t("js.notifications.tooltip.new_message_notification", count: 1))
end
it "prioritizes unseen reviewables bubble over regular notifications" do
current_user.update!(admin: true)
Fabricate(:reviewable)
sign_in(current_user)
visit "/"
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.unread-notifications",
)
expect(page).to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-reviewables",
)
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-pms",
)
end
it "shows regular notifications bubble if there are neither new personal messages nor unseen reviewables" do
Fabricate.times(
3,
:notification,
user: current_user,
high_priority: true,
read: false,
created_at: 8.minutes.ago,
)
sign_in(current_user)
visit "/"
expect(page).to have_selector(
".header-dropdown-toggle.current-user .badge-notification.unread-notifications",
text: "3",
)
expect(
find(".header-dropdown-toggle.current-user .badge-notification.unread-notifications")[:title],
).to eq(I18n.t("js.notifications.tooltip.regular", count: 3))
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-reviewables",
)
expect(page).not_to have_selector(
".header-dropdown-toggle.current-user .badge-notification.with-icon.new-pms",
)
end
context "when resetting password" do
fab!(:current_user) { Fabricate(:user) }
it "does not show search, login, or signup buttons" do
email_token =
current_user.email_tokens.create!(
email: current_user.email,
scope: EmailToken.scopes[:password_reset],
)
visit "/u/password-reset/#{email_token.token}"
expect(page).not_to have_css("button.login-button")
expect(page).not_to have_css("button.sign-up-button")
expect(page).not_to have_css(".search-dropdown #search-button")
end
end
context "when logged in and login required" do
fab!(:current_user) { Fabricate(:user) }
it "displays current user when logged in and login required" do
SiteSetting.login_required = true
sign_in(current_user)
visit "/"
expect(page).not_to have_css("button.login-button")
expect(page).not_to have_css("button.sign-up-button")
expect(page).to have_css("#search-button")
expect(page).to have_css("button.btn-sidebar-toggle")
expect(page).to have_css("#current-user")
end
end
context "when cmd + f keyboard shortcut pressed - when within a topic with 20+ posts" do
before { sign_in(current_user) }
fab!(:posts) { Fabricate.times(21, :post, topic: topic) }
it "opens search on first press, and closes on the second" do
visit "/t/#{topic.slug}/#{topic.id}"
header.search_in_topic_keyboard_shortcut
expect(search).to have_search_menu_visible
header.search_in_topic_keyboard_shortcut
expect(search).to have_no_search_menu_visible
end
end
describe "mobile topic-info" do
fab!(:topic)
fab!(:posts) { Fabricate.times(21, :post, topic: topic) }
it "only shows when scrolled down", mobile: true do
visit "/t/#{topic.slug}/#{topic.id}"
expect(page).to have_css("#topic-title") # Main topic title
expect(page).to have_css("header.d-header .auth-buttons .login-button") # header buttons visible when no topic-info in header
page.execute_script("document.querySelector('#post_4').scrollIntoView()")
expect(page).not_to have_css("header.d-header .auth-buttons .login-button") # No header buttons
expect(page).to have_css("header.d-header .title-wrapper .topic-link") # Title is shown in header
page.execute_script("window.scrollTo(0, 0)")
expect(page).to have_css("#topic-title") # Main topic title
expect(page).to have_css("header.d-header .auth-buttons .login-button") # header buttons visible when no topic-info in header
end
it "shows when navigating direct to a later post", mobile: true do
visit "/t/#{topic.slug}/#{topic.id}/4"
expect(page).not_to have_css("header.d-header .auth-buttons .login-button") # No header buttons
expect(page).to have_css("header.d-header .title-wrapper .topic-link") # Title is shown in header
end
it "shows when jumping from OP to much later post", mobile: true do
visit "/t/#{topic.slug}/#{topic.id}"
expect(page).to have_css("#topic-title") # Main topic title
expect(page).to have_css("header.d-header .auth-buttons .login-button") # header buttons visible when no topic-info in header
page.execute_script("Discourse.visit('/t/#{topic.slug}/#{topic.id}/21');")
expect(page).to have_css("#post_21")
expect(page).not_to have_css("header.d-header .auth-buttons .login-button") # No header buttons
expect(page).to have_css("header.d-header .title-wrapper .topic-link") # Title is shown in header
end
it "shows and hides do-not-disturb icon" do
sign_in current_user
visit "/"
header = find(".d-header")
expect(header).not_to have_css(".do-not-disturb-background")
current_user.publish_do_not_disturb(ends_at: 1.hour.from_now)
expect(header).to have_css(".d-header .do-not-disturb-background")
current_user.publish_do_not_disturb(ends_at: 1.second.from_now)
expect(header).not_to have_css(".d-header .do-not-disturb-background")
end
end
end