diff --git a/templates/devtest/buttons.tmpl b/templates/devtest/buttons.tmpl
index 23caca2a65..909a4061a3 100644
--- a/templates/devtest/buttons.tmpl
+++ b/templates/devtest/buttons.tmpl
@@ -19,7 +19,7 @@
-
+
{{svg "octicon-person"}}
{{ctx.Locale.Tr "user.follow"}}
@@ -30,7 +30,7 @@
-
+
{{svg "octicon-person"}}
{{ctx.Locale.Tr "user.unfollow"}}
@@ -41,7 +41,7 @@
-
+
{{svg "octicon-trash"}}
Delete
diff --git a/tests/e2e/buttons.test.e2e.ts b/tests/e2e/buttons.test.e2e.ts
index 8e3a0d42b3..265e432d48 100644
--- a/tests/e2e/buttons.test.e2e.ts
+++ b/tests/e2e/buttons.test.e2e.ts
@@ -33,7 +33,7 @@ test('Buttons and other controls have consistent height', async ({page}) => {
expect(buttonHeight).toBe(purgeButtonHeight);
});
-test('Button visuals', async ({page}) => {
+test('Button visuals', async ({browser}) => {
async function getButtonProperties(page, selector) {
return await page.locator(selector).evaluate((el) => {
// In Firefox getComputedStyle is undefined if returned from evaluate
@@ -41,32 +41,48 @@ test('Button visuals', async ({page}) => {
return {
backgroundColor: s.backgroundColor,
fontWeight: s.fontWeight,
+ opacity: s.opacity,
+ pointerEvents: s.pointerEvents,
};
});
}
- // const context = await browser.newContext({javaScriptEnabled: false});
- // const page = await context.newPage();
+ const context = await browser.newContext({javaScriptEnabled: false});
+ const page = await context.newPage();
const response = await page.goto('/devtest/buttons');
expect(response?.status()).toBe(200);
const transparent = 'rgba(0, 0, 0, 0)';
- const primary = await getButtonProperties(page, 'button.primary');
- const secondary = await getButtonProperties(page, 'button.secondary');
- const danger = await getButtonProperties(page, 'button.danger');
+ const primary = await getButtonProperties(page, 'button.primary:not(.disabled)');
+ const secondary = await getButtonProperties(page, 'button.secondary:not(.disabled)');
+ const danger = await getButtonProperties(page, 'button.danger:not(.disabled)');
- // Evaluate that all buttons have background-color specified
- expect(primary.backgroundColor).not.toBe(transparent);
- expect(secondary.backgroundColor).not.toBe(transparent);
- expect(danger.backgroundColor).not.toBe(transparent);
+ for (const item of [primary, secondary, danger]) {
+ // Evaluate that all buttons have background-color specified
+ expect(item.backgroundColor).not.toBe(transparent);
+ // Evaluate font weights
+ expect(item.fontWeight).toBe('500');
+ // Evaluate opacity
+ expect(item.opacity).toBe('1');
+ }
- // Evaluate that their background-colors are different
+ // Evaluate that background-colors are different
expect(primary.backgroundColor).not.toBe(secondary.backgroundColor);
expect(primary.backgroundColor).not.toBe(danger.backgroundColor);
- // Evaluate font weights
- expect(primary.fontWeight).toBe('500');
- expect(secondary.fontWeight).toBe('500');
- expect(danger.fontWeight).toBe('500');
+ const primaryDisabled = await getButtonProperties(page, '.button.primary.disabled');
+ const secondaryDisabled = await getButtonProperties(page, '.button.secondary.disabled');
+ const dangerDisabled = await getButtonProperties(page, '.button.danger.disabled');
+
+ for (const item of [primaryDisabled, secondaryDisabled, dangerDisabled]) {
+ // Evaluate opacity
+ expect(item.opacity).toBe('0.55');
+ // Evaluate pointer-events
+ expect(item.pointerEvents).toBe('none');
+
+ // Evaluate other properties of non-disabled buttons
+ expect(item.backgroundColor).not.toBe(transparent);
+ expect(item.fontWeight).toBe('500');
+ }
});
diff --git a/web_src/css/modules/button.css b/web_src/css/modules/button.css
index 1f14961a03..011e89c32f 100644
--- a/web_src/css/modules/button.css
+++ b/web_src/css/modules/button.css
@@ -36,6 +36,11 @@
&:focus {
text-decoration: none;
}
+
+ &.disabled {
+ opacity: var(--opacity-disabled);
+ pointer-events: none;
+ }
}
.button.primary {