discourse/spec/system/page_objects/components/d_menu.rb
Martin Brennan fc98ce9a72
FEATURE: Hover menu for all chat channels in sidebar (#34727)
This commit introduces a menu on an [...] button on hover
of DMs and public chat channels.

When you click on the menu you will see the following
options:

* Change the notification level for the channel
* Mute or unmute the channel
* Go directly to the channel settings
* Leave the channel
* Star or unstar the channel

Over time we may add more items to this menu, these are
just the most common actions for now.

This commit also moves the hovering functionality for sidebar
links to JS, in case we need to modify when the link should
stop hovering, e.g. if it's still inside the menu maybe we
don't want to.

Also added `@suffixIcon` option to `DButton` for the >
in the dropdown

---------

Co-authored-by: Keegan George <kgeorge13@gmail.com>
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2026-01-05 10:59:00 +10:00

65 lines
1.5 KiB
Ruby
Vendored

# frozen_string_literal: true
module PageObjects
module Components
class DMenu < PageObjects::Components::Base
attr_reader :component
def initialize(trigger_input, identifier = nil)
if trigger_input.is_a?(Capybara::Node::Element)
@component = trigger_input
else
@component = find(trigger_input)
end
@identifier = identifier
end
def expand
raise "DMenu is already expanded" if is_expanded?
component.click
end
def collapse
raise "DMenu is already collapsed" if is_collapsed?
component.click
end
def is_expanded?
component["aria-expanded"] == "true"
end
def is_collapsed?
!is_expanded?
end
def portal_with_identifier_selector
if @identifier.nil?
"#d-menu-portals"
else
"#d-menu-portals [data-identifier=\"#{@identifier}\"]"
end
end
def option(selector, match = nil)
params = {}
params[:match] = match if match
within(portal_with_identifier_selector, visible: false) { find(selector, **params) }
end
def has_option?(selector, text = nil)
params = {}
params[:text] = text if text
within(portal_with_identifier_selector) { has_css?(selector, **params) }
end
def has_no_option?(selector)
within(portal_with_identifier_selector) { has_no_css?(selector) }
end
def has_value?(value)
component.has_text?(value)
end
end
end
end