Skip to content

Commit

Permalink
fix: detail scroll not being able to scroll all the way down (#3304)
Browse files Browse the repository at this point in the history
  • Loading branch information
hugo-vrijswijk authored Jul 18, 2024
1 parent 4c02e9b commit b85a177
Show file tree
Hide file tree
Showing 46 changed files with 204 additions and 184 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/elements/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
},
"homepage": "https://github.com/stryker-mutator/mutation-testing-elements/tree/master/packages/elements#readme",
"devDependencies": {
"@lit-labs/observers": "^2.0.2",
"@playwright/test": "1.45.2",
"@tailwindcss/forms": "0.5.7",
"@types/express": "4.17.21",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class MutationTestReportDrawerMutant extends RealTimeElement {
}

private renderDetail() {
return html`<ul class="mb-6 mr-12">
return html`<ul class="mb-12 mr-3">
${this.mutant?.killedByTests?.map((test) =>
renderDetailLine('This mutant was killed by this test', html`${renderEmoji('🎯', 'killed')} ${describeTest(test)}`),
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class MutationTestReportDrawerTestComponent extends RealTimeElement {
);
}
private renderDetail() {
return html`<ul class="mb-6 mr-12">
return html`<ul class="mb-12 mr-3">
${this.test?.killedMutants?.map((mutant) =>
renderDetailLine('This test killed this mutant', html`${renderEmoji('🎯', 'killed')} ${describeMutant(mutant)}`),
)}
Expand Down
4 changes: 0 additions & 4 deletions packages/elements/src/components/drawer/drawer.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@
}
:host([mode='open']) {
@apply h-1/2;

.scrollable {
@apply h-full overflow-y-auto overflow-x-hidden;
}
}
43 changes: 26 additions & 17 deletions packages/elements/src/components/drawer/drawer.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ResizeController } from '@lit-labs/observers/resize-controller.js';
import { html, LitElement, nothing, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { renderIf } from '../../lib/html-helpers.js';
import { tailwind } from '../../style/index.js';
import { renderEmoji } from '../drawer-mutant/util.js';
Expand Down Expand Up @@ -30,10 +32,18 @@ export class MutationTestReportDrawer extends LitElement {
}
}

#drawerResizeObserver: ResizeController<Pick<DOMRectReadOnly, 'width' | 'height'>>;

constructor() {
super();
this.mode = 'closed';
this.hasDetail = false;
this.#drawerResizeObserver = new ResizeController(this, {
callback: (entries) => {
const contentRect = entries[0]?.contentRect;
return { width: contentRect?.width ?? 0, height: contentRect?.height ?? 0 };
},
});
}

public toggleReadMore = (event: MouseEvent) => {
Expand All @@ -47,23 +57,22 @@ export class MutationTestReportDrawer extends LitElement {
};

render() {
return html`<aside @click="${(event: Event) => event.stopPropagation()}">
<div class="mx-6">
<header class="w-full py-4">
<h2>
<slot name="header"></slot>
${renderIf(
this.hasDetail,
html`<button data-testId="btnReadMoreToggle" class="ml-2 align-middle" @click="${this.toggleReadMore}"
>${this.toggleMoreLabel}</button
>`,
)}
</h2>
</header>
<div class="scrollable container fixed motion-safe:transition-max-width">
<slot name="summary"></slot>
${renderIf(this.hasDetail && this.mode === 'open', html`<slot name="detail"></slot>`)}
</div>
const height = this.#drawerResizeObserver.value?.height;
const classes = styleMap({ [`height`]: height ? `${height}px` : undefined });

return html`<aside @click="${(event: Event) => event.stopPropagation()}" style="${classes}" class="ml-6 mr-3 mt-4 overflow-y-auto">
<header class="w-full pb-4">
<h2>
<slot name="header"></slot>
${renderIf(
this.hasDetail,
html`<button data-testId="btnReadMoreToggle" class="ml-2 align-middle" @click="${this.toggleReadMore}">${this.toggleMoreLabel}</button>`,
)}
</h2>
</header>
<div class="motion-safe:transition-max-width">
<slot name="summary"></slot>
${renderIf(this.hasDetail && this.mode === 'open', html`<slot name="detail"></slot>`)}
</div>
</aside>`;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/components/drawer/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { DrawerMode } from './drawer.component.js';

export const renderDrawer = ({ hasDetail, mode }: { hasDetail: boolean; mode: DrawerMode }, content: TemplateResult | typeof nothing) =>
html`<mte-drawer
class="container fixed bottom-0 z-10 overflow-hidden rounded-t-3xl bg-gray-200/60 shadow-xl backdrop-blur-lg motion-safe:transition-[height,max-width] motion-safe:duration-200"
class="container fixed bottom-0 z-10 rounded-t-3xl bg-gray-200/60 shadow-xl backdrop-blur-lg motion-safe:transition-[height,max-width] motion-safe:duration-200"
?hasDetail=${hasDetail}
.mode="${mode}"
>
Expand Down
93 changes: 93 additions & 0 deletions packages/elements/test/integration/drawer-mutant.it.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { MutantDot } from './po/MutantDot.po.js';
import type { Drawer } from './po/Drawer.po.js';
import { ReportPage } from './po/ReportPage.js';
import { actScreenshotMatch } from './lib/helpers.js';
import { test, expect } from '@playwright/test';

test.describe('Drawer mutant view', () => {
let page: ReportPage;

test.beforeEach(async ({ page: p }) => {
page = new ReportPage(p);
await page.navigateTo('test-files-example/#mutant/deep-merge.ts');
});

test.describe('when a mutant is opened', () => {
let drawer: Drawer;
let mutant: MutantDot;
test.beforeEach(async () => {
mutant = page.mutantView.mutantDot(20);
await mutant.toggle();
drawer = page.mutantView.mutantDrawer();
await page.mutantView.scrollToCode();
});

test('should show a summary in the drawer when a mutant is clicked', async () => {
await drawer.whenHalfOpen();
await expect(drawer.header).toHaveText('👽 ConditionalExpression Survived (15:41)');
});

test('should look as expected', async ({ page: p }, testInfo) => {
await drawer.whenHalfOpen();
await actScreenshotMatch(p, testInfo);
});

test('should look as expected in dark mode', async ({ page: p }, testInfo) => {
await page.themeSelector.select('dark');
await drawer.whenHalfOpen();
await actScreenshotMatch(p, testInfo);
});

test('should show the statusReason', async ({ page: p }, testInfo) => {
// Mutant 17 has a statusReason
await page.mutantView.mutantDot(17).toggle();
await drawer.whenHalfOpen();
await expect(drawer.summary()).toContainText('Survived despite covered by 3 tests');
await actScreenshotMatch(p, testInfo);
});

test('should close the drawer when deselecting the mutant', async () => {
await mutant.toggle();
await drawer.whenClosed();
});

test('should show the details of the next mutant when another mutant is selected', async () => {
await page.mutantView.mutantDot(24).toggle();
await drawer.whenHalfOpen();
await expect(drawer.header).toHaveText('👽 ConditionalExpression Survived (15:77)');
});

test('should hide the drawer when the user clicks somewhere else', async () => {
await page.mutantView.clickOnCode();
await drawer.whenClosed();
});

test('should not hide the drawer when the user clicks somewhere on the drawer', async () => {
await drawer.whenHalfOpen();
await drawer.clickOnHeader();

await drawer.whenHalfOpen();
});

test.describe('when "read more" is toggled', () => {
test.beforeEach(async () => {
await drawer.whenHalfOpen();
await drawer.toggleReadMore();
await drawer.whenOpen();
});

test('should show the details', async () => {
await expect(drawer.details()).toBeVisible();
});

test('should look as expected', async ({ page: p }, testInfo) => {
await actScreenshotMatch(p, testInfo);
});

test('should look as expected in dark mode', async ({ page: p }, testInfo) => {
await page.themeSelector.select('dark');
await actScreenshotMatch(p, testInfo);
});
});
});
});
70 changes: 70 additions & 0 deletions packages/elements/test/integration/drawer-test.it.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { Drawer } from './po/Drawer.po.js';
import { ReportPage } from './po/ReportPage.js';
import { actScreenshotMatch } from './lib/helpers.js';
import type { TestDot } from './po/TestDot.po.js';
import { test, expect } from '@playwright/test';

test.describe('Drawer test view', () => {
let page: ReportPage;
let drawer: Drawer;
let dot: TestDot;

test.beforeEach(async ({ page: p }) => {
page = new ReportPage(p);
await page.navigateTo('lighthouse-example/#test/metrics/interactive-test.js');
dot = page.testView.testDot(597);
await dot.toggle();
drawer = page.testView.testDrawer;
await page.testView.scrollToCode();
});

test('should show a summary in the drawer when a test is selected', async () => {
await drawer.whenHalfOpen();
await expect(drawer.header).toHaveText('✅ Performance: interactive audit should compute interactive [Killing] (22:4)');
});

test('should look as expected', async ({ page: p }, testInfo) => {
await drawer.whenHalfOpen();
await actScreenshotMatch(p, testInfo);
});

test('should look as expected in dark mode', async ({ page: p }, testInfo) => {
await page.themeSelector.select('dark');
await drawer.whenHalfOpen();
await actScreenshotMatch(p, testInfo);
});

test('should hide the drawer when the user clicks somewhere else', async () => {
await page.testView.clickOnCode();
await drawer.whenClosed();
await expect(drawer.details()).not.toBeVisible();
});

test('should not hide the drawer when the user clicks somewhere on the drawer', async () => {
await drawer.whenHalfOpen();
await drawer.clickOnHeader();

await drawer.whenHalfOpen();
});

test.describe('when "read more" is toggled', () => {
test.beforeEach(async () => {
await drawer.whenHalfOpen();
await drawer.toggleReadMore();
await drawer.whenOpen();
});

test('should show the details', async () => {
await expect(drawer.details()).toBeVisible();
});

test('should look as expected', async ({ page: p }, testInfo) => {
await actScreenshotMatch(p, testInfo);
});

test('should look as expected in dark mode', async ({ page: p }, testInfo) => {
await page.themeSelector.select('dark');
await actScreenshotMatch(p, testInfo);
});
});
});
Loading

0 comments on commit b85a177

Please sign in to comment.