diff --git a/templates/devtest/dropdown.tmpl b/templates/devtest/dropdown.tmpl new file mode 100644 index 0000000000..9df58758d4 --- /dev/null +++ b/templates/devtest/dropdown.tmpl @@ -0,0 +1,74 @@ +{{template "base/head" .}} + +
+

Dropdown

+ a.k.a. overflow menu, ellipsis menu + +
+ + + + + +
+ +
+ +{{template "base/footer" .}} diff --git a/templates/explore/search.tmpl b/templates/explore/search.tmpl index 446d23f253..e7e6b740c4 100644 --- a/templates/explore/search.tmpl +++ b/templates/explore/search.tmpl @@ -11,7 +11,7 @@ {{end}} diff --git a/tests/e2e/actions.test.e2e.ts b/tests/e2e/actions.test.e2e.ts index 4a1b8a3ec2..2f5d09e561 100644 --- a/tests/e2e/actions.test.e2e.ts +++ b/tests/e2e/actions.test.e2e.ts @@ -70,6 +70,53 @@ test.describe('Workflow Authenticated user2', () => { test('dispatch success', async ({page}) => { await dispatchSuccess(page); }); + + test('Disable/enable workflow', async ({page}) => { + await page.goto('/user2/test_workflows/actions?workflow=test-dispatch.yml'); + + const menuOpener = page.locator('.filter.menu details.dropdown > summary'); + const disableButton = page.locator('a[data-url^="/user2/test_workflows/actions/disable"]'); + const enableButton = page.locator('a[data-url^="/user2/test_workflows/actions/enable"]'); + const disabledLabel = page.locator('.vertical.menu .item.active .ui.label').getByText('Disabled'); + const flashBanner = page.locator('#flash-message'); + + // Overflow menu is hidden + await expect(disableButton).toBeHidden(); + await expect(enableButton).toBeHidden(); + + await menuOpener.click(); + + // The current "Enabled" state is what previous tests left, but this test is built to not care + if (await disableButton.isVisible()) { + // Assert elemeents on page + await expect(enableButton).toBeHidden(); + await expect(disabledLabel).toBeHidden(); + + // Flip the state + await disableButton.click(); + await flashBanner.waitFor(); + await menuOpener.click(); + + // Assert elemeents on page + await expect(enableButton).toBeVisible(); + await expect(disableButton).toBeHidden(); + await expect(disabledLabel).toBeVisible(); + } else { + // Assert elemeents on page + await expect(enableButton).toBeVisible(); + await expect(disabledLabel).toBeVisible(); + + // Flip the state + await enableButton.click(); + await flashBanner.waitFor(); + await menuOpener.click(); + + // Assert elemeents on page + await expect(enableButton).toBeHidden(); + await expect(disableButton).toBeVisible(); + await expect(disabledLabel).toBeHidden(); + } + }); }); test('workflow dispatch box not available for unauthenticated users', async ({page}) => { diff --git a/tests/e2e/dropdown.test.e2e.ts b/tests/e2e/dropdown.test.e2e.ts index c4098e102a..e90ea93d6b 100644 --- a/tests/e2e/dropdown.test.e2e.ts +++ b/tests/e2e/dropdown.test.e2e.ts @@ -5,6 +5,7 @@ // templates/shared/user/actions_menu.tmpl // templates/org/header.tmpl // templates/explore/search.tmpl +// templates/devtest/dropdown.tmpl // web_src/js/modules/dropdown.ts // @watch end @@ -226,4 +227,33 @@ test.describe(`Visual properties`, () => { expect(await activeItem.evaluate((el) => getComputedStyle(el).backgroundColor)).toBe('rgb(226, 226, 229)'); expect(await inactiveItem.evaluate((el) => getComputedStyle(el).backgroundColor)).toBe('rgba(0, 0, 0, 0)'); }); + + test('Devtest', async ({browser}) => { + const context = await browser.newContext({javaScriptEnabled: false}); + const page = await context.newPage(); + + // `/devtest` has dropdowns with various combinations of items + await page.goto('/devtest/dropdown'); + + // Dropdown with just 3 items and nothing special + await page.locator(`#dropdown-1 > summary`).click(); + expect(await page.locator(`#dd1_g1_i1`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('4px 4px 0px 0px'); + expect(await page.locator(`#dd1_g1_i2`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px'); + expect(await page.locator(`#dd1_g1_i3`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px 0px 4px 4px'); + await page.keyboard.press('Enter'); // Exit dropdown - page is in noJS mode + + // Dropdown with two groups of items separated with an
+ await page.locator(`#dropdown-2 > summary`).click(); + expect(await page.locator(`#dd2_g1_i1`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('4px 4px 0px 0px'); + expect(await page.locator(`#dd2_g1_i2`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px'); + expect(await page.locator(`#dd2_g1_i3`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px'); + expect(await page.locator(`#dd2_g2_i1`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px'); + expect(await page.locator(`#dd2_g2_i2`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px'); + expect(await page.locator(`#dd2_g2_i3`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('0px 0px 4px 4px'); + await page.keyboard.press('Enter'); // Exit dropdown - page is in noJS mode + + // Dropdown with only one item, which should be completely round + await page.locator(`#dropdown-3 > summary`).click(); + expect(await page.locator(`#dd3_g1_i1`).evaluate((el) => getComputedStyle(el).borderRadius)).toBe('4px'); + }); }); diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index d7cc1dff87..bd294a132f 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -107,7 +107,7 @@ func TestE2e(t *testing.T) { defer test.MockVariableValue(&setting.Quota.Enabled, true)() defer test.MockVariableValue(&testE2eWebRoutes, routers.NormalRoutes())() } - if testname == "buttons.test.e2e" { + if testname == "buttons.test.e2e" || testname == "dropdown.test.e2e" { defer test.MockVariableValue(&setting.IsProd, false)() defer test.MockVariableValue(&testE2eWebRoutes, routers.NormalRoutes())() } diff --git a/web_src/css/modules/dropdown.css b/web_src/css/modules/dropdown.css index dc7e81ed7b..39a8f21b58 100644 --- a/web_src/css/modules/dropdown.css +++ b/web_src/css/modules/dropdown.css @@ -107,6 +107,9 @@ details.dropdown > .content > ul { &:last-of-type > li:last-child { border-radius: 0 0 var(--border-radius) var(--border-radius); } + &:only-of-type > li:only-child { + border-radius: var(--border-radius); + } } /* General styling of list items */