@api-client/ui 0.5.39 → 0.5.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
- package/.aiexclude +0 -3
- package/.cursor/rules/html-and-css-best-practices.mdc +0 -63
- package/.cursor/rules/lit-best-practices.mdc +0 -89
- package/.editorconfig +0 -29
- package/.github/CONTRIBUTING.md +0 -24
- package/.github/instructions/html-and-css-best-practices.instructions.md +0 -70
- package/.github/instructions/lit-best-practices.instructions.md +0 -90
- package/.github/release.yml +0 -14
- package/.github/stale.yml +0 -23
- package/.github/workflows/auto-release.yml +0 -182
- package/.github/workflows/release.yml +0 -82
- package/.prettierrc.js +0 -14
- package/.vscode/settings.json +0 -18
- package/RELEASE.md +0 -163
- package/RELEASE_SETUP.md +0 -235
- package/build/src/demo/DemoPage.d.ts +0 -81
- package/build/src/demo/DemoPage.d.ts.map +0 -1
- package/build/src/demo/DemoPage.js +0 -175
- package/build/src/demo/DemoPage.js.map +0 -1
- package/build/src/demo/DemoStyles.d.ts +0 -3
- package/build/src/demo/DemoStyles.d.ts.map +0 -1
- package/build/src/demo/DemoStyles.js +0 -60
- package/build/src/demo/DemoStyles.js.map +0 -1
- package/build/test/elements/navigation/Navigation.test.d.ts +0 -3
- package/build/test/elements/navigation/Navigation.test.d.ts.map +0 -1
- package/build/test/elements/navigation/Navigation.test.js +0 -113
- package/build/test/elements/navigation/Navigation.test.js.map +0 -1
- package/commitlint.config.cjs +0 -2
- package/demo/elements/authorization/AuthPlugin.js +0 -57
- package/demo/elements/authorization/AuthProxy.js +0 -215
- package/demo/elements/authorization/api-key.html +0 -27
- package/demo/elements/authorization/api-key.ts +0 -44
- package/demo/elements/authorization/basic.html +0 -27
- package/demo/elements/authorization/basic.ts +0 -43
- package/demo/elements/authorization/bearer.html +0 -27
- package/demo/elements/authorization/bearer.ts +0 -43
- package/demo/elements/authorization/env.js +0 -8
- package/demo/elements/authorization/index.html +0 -44
- package/demo/elements/authorization/ntlm.html +0 -27
- package/demo/elements/authorization/ntlm.ts +0 -43
- package/demo/elements/authorization/oauth-authorize.html +0 -75
- package/demo/elements/authorization/oauth-authorize.ts +0 -40
- package/demo/elements/authorization/oauth-error.html +0 -18
- package/demo/elements/authorization/oauth-error.ts +0 -10
- package/demo/elements/authorization/oauth-popup.html +0 -36
- package/demo/elements/authorization/oauth2.html +0 -27
- package/demo/elements/authorization/oauth2.ts +0 -100
- package/demo/elements/authorization/oidc.html +0 -27
- package/demo/elements/authorization/oidc.ts +0 -139
- package/demo/elements/authorization/private.crt +0 -31
- package/demo/elements/authorization/private.csr +0 -28
- package/demo/elements/authorization/private.key +0 -51
- package/demo/elements/authorization/private.pem +0 -31
- package/demo/elements/authorization/redirect.html +0 -20
- package/demo/elements/authorization/ssl-commands.sh +0 -30
- package/demo/elements/authorization/ssl.conf +0 -24
- package/demo/elements/autocomplete/index.html +0 -64
- package/demo/elements/autocomplete/index.ts +0 -171
- package/demo/elements/code-editor/CodeEditorDemo.ts +0 -173
- package/demo/elements/code-editor/index.html +0 -19
- package/demo/elements/context-menu/DemoIcons.ts +0 -21
- package/demo/elements/context-menu/basic.html +0 -25
- package/demo/elements/context-menu/basic.ts +0 -119
- package/demo/elements/context-menu/custom-data.html +0 -25
- package/demo/elements/context-menu/custom-data.ts +0 -62
- package/demo/elements/context-menu/demo.css +0 -28
- package/demo/elements/context-menu/enabled-state.html +0 -25
- package/demo/elements/context-menu/enabled-state.ts +0 -73
- package/demo/elements/context-menu/icons.html +0 -25
- package/demo/elements/context-menu/icons.ts +0 -64
- package/demo/elements/context-menu/index.html +0 -43
- package/demo/elements/context-menu/nested.html +0 -25
- package/demo/elements/context-menu/nestedt.ts +0 -152
- package/demo/elements/context-menu/no-execute.html +0 -25
- package/demo/elements/context-menu/no-execute.ts +0 -134
- package/demo/elements/context-menu/radio-menu.html +0 -25
- package/demo/elements/context-menu/radio-menu.ts +0 -83
- package/demo/elements/context-menu/separators.html +0 -25
- package/demo/elements/context-menu/separators.ts +0 -172
- package/demo/elements/currency/index.html +0 -91
- package/demo/elements/currency/index.ts +0 -352
- package/demo/elements/environment/environment-editor.html +0 -20
- package/demo/elements/environment/environment-editor.ts +0 -49
- package/demo/elements/environment/index.html +0 -33
- package/demo/elements/environment/server-editor.html +0 -20
- package/demo/elements/environment/server-editor.ts +0 -67
- package/demo/elements/environment/variables-editor.html +0 -20
- package/demo/elements/environment/variables-editor.ts +0 -94
- package/demo/elements/har/har-viewer.html +0 -20
- package/demo/elements/har/har-viewer.ts +0 -76
- package/demo/elements/har/har1.har +0 -3044
- package/demo/elements/har/har2.json +0 -439
- package/demo/elements/har/index.html +0 -26
- package/demo/elements/highlight/example.md +0 -27
- package/demo/elements/highlight/index.html +0 -31
- package/demo/elements/highlight/marked-highlight.html +0 -132
- package/demo/elements/highlight/marked-highlight.ts +0 -22
- package/demo/elements/highlight/prism-highlight.html +0 -62
- package/demo/elements/highlight/prism-highlight.ts +0 -17
- package/demo/elements/http/body-editor.html +0 -17
- package/demo/elements/http/body-editor.ts +0 -115
- package/demo/elements/http/headers.html +0 -17
- package/demo/elements/http/headers.ts +0 -59
- package/demo/elements/http/http-assertions.html +0 -20
- package/demo/elements/http/http-assertions.ts +0 -89
- package/demo/elements/http/http-flows.html +0 -23
- package/demo/elements/http/http-flows.ts +0 -89
- package/demo/elements/http/index.html +0 -45
- package/demo/elements/http/request-editor.html +0 -26
- package/demo/elements/http/request-editor.ts +0 -197
- package/demo/elements/http/request-log.html +0 -16
- package/demo/elements/http/request-log.ts +0 -136
- package/demo/elements/http/url-editing.html +0 -17
- package/demo/elements/http/url-editing.ts +0 -112
- package/demo/elements/icons/index.html +0 -81
- package/demo/elements/icons/index.ts +0 -52
- package/demo/elements/index.html +0 -72
- package/demo/elements/mention-textarea/index.html +0 -19
- package/demo/elements/mention-textarea/index.ts +0 -205
- package/demo/elements/navigation/navigation-item.html +0 -49
- package/demo/elements/navigation/navigation-item.ts +0 -131
- package/demo/elements/navigation/navigation.html +0 -20
- package/demo/elements/navigation/navigation.ts +0 -45
- package/demo/elements/project/index.html +0 -29
- package/demo/elements/project/project-run-report.html +0 -20
- package/demo/elements/project/project-run-report.ts +0 -132
- package/demo/elements/project/request-editor.html +0 -23
- package/demo/elements/project/request-editor.ts +0 -232
- package/demo/elements/user/user-avatar.html +0 -17
- package/demo/elements/user/user-avatar.ts +0 -60
- package/demo/env.js +0 -4
- package/demo/index.html +0 -34
- package/demo/layout/index.html +0 -94
- package/demo/layout/index.ts +0 -190
- package/demo/md/DemoStyles.ts +0 -61
- package/demo/md/UiDemoPage.ts +0 -6
- package/demo/md/buttons/button.html +0 -121
- package/demo/md/buttons/button.ts +0 -246
- package/demo/md/buttons/group.html +0 -36
- package/demo/md/buttons/group.ts +0 -171
- package/demo/md/checkbox/index.html +0 -39
- package/demo/md/checkbox/index.ts +0 -220
- package/demo/md/chip/chip.html +0 -70
- package/demo/md/chip/chip.ts +0 -219
- package/demo/md/chip/pawel6c9a.jpg +0 -0
- package/demo/md/collapse/CustomDetail.ts +0 -89
- package/demo/md/collapse/collapse.html +0 -21
- package/demo/md/collapse/collapse.ts +0 -78
- package/demo/md/date-picker/date-picker.ts +0 -336
- package/demo/md/date-picker/index.html +0 -171
- package/demo/md/dialog/confirm-dialog.html +0 -49
- package/demo/md/dialog/confirm-dialog.ts +0 -121
- package/demo/md/dialog/dialog.html +0 -25
- package/demo/md/dialog/dialog.ts +0 -468
- package/demo/md/dropdown-list/index.html +0 -31
- package/demo/md/dropdown-list/index.ts +0 -158
- package/demo/md/icon-button/index.html +0 -122
- package/demo/md/icon-button/index.ts +0 -132
- package/demo/md/index.html +0 -73
- package/demo/md/inputs/input.html +0 -73
- package/demo/md/inputs/input.ts +0 -278
- package/demo/md/inputs/radio.html +0 -39
- package/demo/md/inputs/radio.ts +0 -156
- package/demo/md/inputs/switch.html +0 -45
- package/demo/md/inputs/switch.ts +0 -144
- package/demo/md/list/list.html +0 -65
- package/demo/md/list/list.ts +0 -204
- package/demo/md/listbox/listbox.html +0 -31
- package/demo/md/listbox/listbox.ts +0 -27
- package/demo/md/menu/index.html +0 -19
- package/demo/md/menu/index.ts +0 -514
- package/demo/md/notification/snack.html +0 -21
- package/demo/md/notification/snack.ts +0 -70
- package/demo/md/progress/progress.html +0 -46
- package/demo/md/progress/progress.ts +0 -161
- package/demo/md/segmented-button/index.html +0 -21
- package/demo/md/segmented-button/index.ts +0 -55
- package/demo/md/select/index.html +0 -16
- package/demo/md/select/index.ts +0 -217
- package/demo/md/tabs/tabs.html +0 -40
- package/demo/md/tabs/tabs.ts +0 -214
- package/demo/oauth-popup.html +0 -36
- package/demo/page.css +0 -8
- package/demo/resources/calendar-month.png +0 -0
- package/demo/resources/favorite.png +0 -0
- package/demo/resources/fingerprint.png +0 -0
- package/demo/resources/home-work.png +0 -0
- package/demo/resources/mood.png +0 -0
- package/demo/resources/print.png +0 -0
- package/demo/resources/stars.png +0 -0
- package/demo/resources/theaters.png +0 -0
- package/demo/tsconfig.json +0 -4
- package/eslint.config.js +0 -97
- package/scripts/copy-assets.js +0 -21
- package/scripts/release.js +0 -66
- package/src/demo/DemoPage.ts +0 -169
- package/src/demo/DemoStyles.ts +0 -60
- package/test/README.md +0 -375
- package/test/contextual-menu/ContextMenu.test.ts +0 -760
- package/test/contextual-menu/ContextMenuElement.test.ts +0 -569
- package/test/core/activity.spec.ts +0 -413
- package/test/core/activity_manager.spec.ts +0 -544
- package/test/core/application.spec.ts +0 -218
- package/test/core/fragment.spec.ts +0 -565
- package/test/core/fragment_manager.spec.ts +0 -404
- package/test/core/live_data.spec.ts +0 -558
- package/test/core/renderer.spec.ts +0 -113
- package/test/dom-assertions.test.ts +0 -182
- package/test/elements/MonacoSetup.ts +0 -65
- package/test/elements/authorization/basic-method.test.ts +0 -177
- package/test/elements/authorization/bearer-method.test.ts +0 -143
- package/test/elements/authorization/ntlm-method.test.ts +0 -219
- package/test/elements/authorization/oauth2-client-credentials-method.test.ts +0 -334
- package/test/elements/authorization/oauth2-code-method.test.ts +0 -320
- package/test/elements/authorization/oauth2-custom-grant-method.test.ts +0 -255
- package/test/elements/authorization/oauth2-device-code-method.test.ts +0 -371
- package/test/elements/authorization/oauth2-implicit-method.test.ts +0 -407
- package/test/elements/authorization/oauth2-jwt-method.test.ts +0 -217
- package/test/elements/authorization/oauth2-password-method.test.ts +0 -275
- package/test/elements/authorization/openid-method.test.ts +0 -591
- package/test/elements/autocomplete/autocomplete-input.spec.ts +0 -646
- package/test/elements/code-editor/code-editor.accessibility.test.ts +0 -298
- package/test/elements/code-editor/code-editor.test.ts +0 -574
- package/test/elements/currency/CurrencyPicker.accessibility.test.ts +0 -328
- package/test/elements/currency/CurrencyPicker.core.test.ts +0 -318
- package/test/elements/currency/CurrencyPicker.integration.test.ts +0 -482
- package/test/elements/currency/CurrencyPicker.test.ts +0 -486
- package/test/elements/data-table/DataTable.browser.test.ts +0 -649
- package/test/elements/har/HarUtils.test.ts +0 -45
- package/test/elements/har/HarViewerElement.test.ts +0 -687
- package/test/elements/har/test-data/har1.har +0 -3044
- package/test/elements/highlight/MarkedHighlightElement.test.ts +0 -452
- package/test/elements/highlight/PrismHighlightElement.test.ts +0 -79
- package/test/elements/highlight/PrismHighlighter.test.ts +0 -94
- package/test/elements/highlight/remoteSanitization.md +0 -1
- package/test/elements/highlight/test.md +0 -3
- package/test/elements/highlight/test1.md +0 -3
- package/test/elements/highlight/test2.md +0 -1
- package/test/elements/http/BodyFormdataEditorElement.test.ts +0 -482
- package/test/elements/http/BodyMultipartEditorElement.test.ts +0 -658
- package/test/elements/http/BodyRawEditorElement.test.ts +0 -90
- package/test/elements/http/CertificateAdd.test.ts +0 -457
- package/test/elements/http/HttpAssertions.test.ts +0 -994
- package/test/elements/http/HttpFlows.test.ts +0 -502
- package/test/elements/http/UrlEncodeUtils.test.ts +0 -202
- package/test/elements/layout/SplitItem.test.ts +0 -440
- package/test/elements/layout/SplitLayoutManager.test.ts +0 -1501
- package/test/elements/layout/SplitPanel.test.ts +0 -1109
- package/test/elements/mention-textarea/MentionTextArea.basic.test.ts +0 -114
- package/test/elements/mention-textarea/MentionTextArea.test.ts +0 -613
- package/test/elements/navigation/Navigation.test.ts +0 -120
- package/test/env.ts +0 -15
- package/test/events/EventTypes.test.ts +0 -363
- package/test/events/EventsTestHelpers.ts +0 -16
- package/test/helpers/TestUtils.ts +0 -243
- package/test/helpers/UiMock.ts +0 -185
- package/test/lib/Dom.test.ts +0 -231
- package/test/md/button/UiButton.test.ts +0 -347
- package/test/md/button/UiIconButton.test.ts +0 -155
- package/test/md/chip/UiChip.test.ts +0 -219
- package/test/md/collapse/UiCollapse.test.ts +0 -250
- package/test/md/collapse/flex-layout.test.ts +0 -105
- package/test/md/date-time/DateTime.test.ts +0 -348
- package/test/md/dialog/UiConfirmDialog.test.ts +0 -131
- package/test/md/dialog/UiDialog.test.ts +0 -759
- package/test/md/menu/Menu.test.ts +0 -855
- package/test/md/menu/MenuIntegration.test.ts +0 -426
- package/test/md/menu/MenuItem.test.ts +0 -652
- package/test/md/menu/SubMenu.test.ts +0 -410
- package/test/md/progress/UiCircularProgressElement.test.ts +0 -481
- package/test/md/progress/UiProgressElement.test.ts +0 -117
- package/test/md/progress/UiRangeElement.test.ts +0 -156
- package/test/md/select/Select.test.ts +0 -925
- package/test/plugins/takeScreenshotPlugin.js +0 -35
- package/test/setup.test.ts +0 -217
- package/test/setup.ts +0 -117
- package/test/tsconfig.json +0 -7
- package/web-dev-server.config.js +0 -21
- package/web-test-runner.config.js +0 -90
|
@@ -1,649 +0,0 @@
|
|
|
1
|
-
import { fixture, assert, nextFrame, html, defineCE, unsafeStatic } from '@open-wc/testing'
|
|
2
|
-
import { TemplateResult } from 'lit'
|
|
3
|
-
import sinon from 'sinon'
|
|
4
|
-
import { sendKeys } from '@web/test-runner-commands'
|
|
5
|
-
import { DataTable, type EventCellInfo } from '../../../src/elements/data-table/DataTable.js'
|
|
6
|
-
import { LiveData } from '../../../src/reactive/LiveData.js'
|
|
7
|
-
|
|
8
|
-
class TestDataTable extends DataTable<TestItem> {
|
|
9
|
-
override renderHeader(): TemplateResult[] {
|
|
10
|
-
return [
|
|
11
|
-
this.renderHeaderCell('C1', 0, { sort: 'name' }),
|
|
12
|
-
this.renderHeaderCell('C2', 1, { ariaLabel: 'C2 label' }),
|
|
13
|
-
this.renderHeaderCell('C3', 2, { classes: ['my-class'] }),
|
|
14
|
-
this.renderHeaderCell(`C4`, 3, { delegateFocus: true }),
|
|
15
|
-
this.renderHeaderCell(`C5`, 4, { data: { foo: 'bar' } }),
|
|
16
|
-
this.renderHeaderCell(`C6`, 5, { sort: 'other' }),
|
|
17
|
-
]
|
|
18
|
-
}
|
|
19
|
-
override renderRowValues(item: TestItem, index: number): TemplateResult[] {
|
|
20
|
-
return [
|
|
21
|
-
this.renderCell(html`R${index}.1`, index, 0, { classes: ['primary-cell'], isPrimary: true }),
|
|
22
|
-
this.renderCell(html`R${index}.2`, index, 1, { ariaLabel: `R${index}.2 Label` }),
|
|
23
|
-
this.renderCell(html`R${index}.3`, index, 2, { classes: ['my-class'] }),
|
|
24
|
-
this.renderCell(html`<button name="r.${index}.4" value="R${index}.4" tabindex="-1">Demo</button>`, index, 3, {
|
|
25
|
-
delegateFocus: true,
|
|
26
|
-
}),
|
|
27
|
-
this.renderCell(html`R${index}.5`, index, 4, { data: { foo: 'row-bar' } }),
|
|
28
|
-
this.renderCell(html`R${index}.6`, index, 5),
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
override infoFromEvent(e: Event): EventCellInfo | undefined {
|
|
33
|
-
return super.infoFromEvent(e)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const tagName = defineCE(TestDataTable)
|
|
38
|
-
const tag = unsafeStatic(tagName)
|
|
39
|
-
|
|
40
|
-
interface TestItem {
|
|
41
|
-
name: string
|
|
42
|
-
value: number
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function generateItems(size = 5): LiveData<TestItem[]> {
|
|
46
|
-
const result: TestItem[] = []
|
|
47
|
-
for (let i = 0; i < size; i++) {
|
|
48
|
-
result.push({
|
|
49
|
-
name: `v${i}`,
|
|
50
|
-
value: i,
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
return new LiveData(result)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
describe('DataTable', () => {
|
|
57
|
-
async function basicFixture<T>(items: LiveData<T[]>): Promise<TestDataTable> {
|
|
58
|
-
return fixture(html`<${tag} .items="${items}"></${tag}>`)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function singleSelectionFixture<T>(items: LiveData<T[]>): Promise<TestDataTable> {
|
|
62
|
-
return fixture(html`<${tag} .items="${items}" selection="single"></${tag}>`)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function sortedFixture<T>(items: LiveData<T[]>): Promise<TestDataTable> {
|
|
66
|
-
return fixture(html`<${tag} .items="${items}" sort="name"></${tag}>`)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function multiSelectionFixture<T>(items: LiveData<T[]>): Promise<TestDataTable> {
|
|
70
|
-
return fixture(html`<${tag} .items="${items}" selection="multi"></${tag}>`)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
describe('Basic tests', () => {
|
|
74
|
-
it('renders the table with correct number of rows and columns', async () => {
|
|
75
|
-
const items = generateItems(3)
|
|
76
|
-
const element = await basicFixture<TestItem>(items)
|
|
77
|
-
await nextFrame()
|
|
78
|
-
const rows = element.shadowRoot!.querySelectorAll('tr')
|
|
79
|
-
assert.equal(rows.length, items.value.length + 1, 'has all rows') // +1 for header row
|
|
80
|
-
|
|
81
|
-
const headerCells = element.shadowRoot!.querySelectorAll('thead th')
|
|
82
|
-
assert.equal(headerCells.length, 6, 'has all header cells')
|
|
83
|
-
|
|
84
|
-
const firstRowCells = rows[1].querySelectorAll('td, th')
|
|
85
|
-
assert.equal(firstRowCells.length, 6, 'has all row cells')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('renders the empty state when there are no items', async () => {
|
|
89
|
-
const element = await basicFixture<TestItem>(new LiveData([]))
|
|
90
|
-
await nextFrame()
|
|
91
|
-
|
|
92
|
-
const emptyState = element.shadowRoot!.querySelector('.empty')
|
|
93
|
-
assert.exists(emptyState)
|
|
94
|
-
assert.equal(emptyState!.textContent, 'No data to display.')
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('dispatches a select event when an item is selected', async () => {
|
|
98
|
-
const items = generateItems(2)
|
|
99
|
-
const element = await singleSelectionFixture<TestItem>(items)
|
|
100
|
-
await nextFrame()
|
|
101
|
-
|
|
102
|
-
const selectSpy = sinon.spy()
|
|
103
|
-
element.addEventListener('select', selectSpy)
|
|
104
|
-
|
|
105
|
-
const cell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
106
|
-
cell.click()
|
|
107
|
-
await nextFrame()
|
|
108
|
-
|
|
109
|
-
assert.isTrue(selectSpy.calledOnce)
|
|
110
|
-
assert.deepEqual(selectSpy.firstCall.args[0].detail.selectedItems, [items.value[0]])
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('dispatches an activate event when an item is activated (primary colum)', async () => {
|
|
114
|
-
const items = generateItems(2)
|
|
115
|
-
const element = await basicFixture<TestItem>(items)
|
|
116
|
-
element.active = true
|
|
117
|
-
await nextFrame()
|
|
118
|
-
|
|
119
|
-
const activateSpy = sinon.spy()
|
|
120
|
-
element.addEventListener('activate', activateSpy)
|
|
121
|
-
|
|
122
|
-
const event = new MouseEvent('click', { detail: 2, bubbles: true, composed: true })
|
|
123
|
-
const cell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
124
|
-
cell.dispatchEvent(event)
|
|
125
|
-
await nextFrame()
|
|
126
|
-
|
|
127
|
-
assert.isTrue(activateSpy.calledOnce)
|
|
128
|
-
assert.deepEqual(activateSpy.firstCall.args[0].detail, items.value[0])
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
it('dispatches an activate event when an item is activated (any colum)', async () => {
|
|
132
|
-
const items = generateItems(2)
|
|
133
|
-
const element = await basicFixture<TestItem>(items)
|
|
134
|
-
element.active = true
|
|
135
|
-
await nextFrame()
|
|
136
|
-
|
|
137
|
-
const activateSpy = sinon.spy()
|
|
138
|
-
element.addEventListener('activate', activateSpy)
|
|
139
|
-
|
|
140
|
-
const event = new MouseEvent('click', { detail: 2, bubbles: true, composed: true })
|
|
141
|
-
const cell = element.shadowRoot!.querySelector(`[data-col="2"][data-row="1"]`) as HTMLElement
|
|
142
|
-
cell.dispatchEvent(event)
|
|
143
|
-
await nextFrame()
|
|
144
|
-
|
|
145
|
-
assert.isTrue(activateSpy.calledOnce)
|
|
146
|
-
assert.deepEqual(activateSpy.firstCall.args[0].detail, items.value[0])
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('dispatches a sort event when a header is clicked', async () => {
|
|
150
|
-
const items = generateItems(2)
|
|
151
|
-
const element = await basicFixture<TestItem>(items)
|
|
152
|
-
await nextFrame()
|
|
153
|
-
|
|
154
|
-
const sortSpy = sinon.spy()
|
|
155
|
-
element.addEventListener('sort', sortSpy)
|
|
156
|
-
const headerCell = element.shadowRoot!.querySelectorAll('th')[0]
|
|
157
|
-
headerCell.click()
|
|
158
|
-
await nextFrame()
|
|
159
|
-
|
|
160
|
-
assert.isTrue(sortSpy.calledOnce)
|
|
161
|
-
assert.deepEqual(sortSpy.firstCall.args[0].detail, { column: 'name', direction: 'asc' })
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
it('toggle the sorting direction when the same header is clicked', async () => {
|
|
165
|
-
const items = generateItems(2)
|
|
166
|
-
const element = await basicFixture<TestItem>(items)
|
|
167
|
-
await nextFrame()
|
|
168
|
-
|
|
169
|
-
const sortSpy = sinon.spy()
|
|
170
|
-
element.addEventListener('sort', sortSpy)
|
|
171
|
-
const headerCell = element.shadowRoot!.querySelectorAll('th')[0]
|
|
172
|
-
headerCell.click()
|
|
173
|
-
await nextFrame()
|
|
174
|
-
assert.deepEqual(sortSpy.firstCall.args[0].detail, { column: 'name', direction: 'asc' })
|
|
175
|
-
headerCell.click()
|
|
176
|
-
await nextFrame()
|
|
177
|
-
|
|
178
|
-
assert.deepEqual(sortSpy.secondCall.args[0].detail, { column: 'name', direction: 'desc' })
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('dispatches a scrollend event when the sentinel is visible', async () => {
|
|
182
|
-
const items = generateItems(2)
|
|
183
|
-
const element = await basicFixture<TestItem>(items)
|
|
184
|
-
element.overflow = true
|
|
185
|
-
await nextFrame()
|
|
186
|
-
|
|
187
|
-
const scrollendSpy = sinon.spy()
|
|
188
|
-
element.addEventListener('scrollend', scrollendSpy)
|
|
189
|
-
|
|
190
|
-
// Simulate the sentinel intersecting
|
|
191
|
-
const sentinel = element.shadowRoot!.querySelector('.scroll-sentinel')!
|
|
192
|
-
const entries = [
|
|
193
|
-
{
|
|
194
|
-
isIntersecting: true,
|
|
195
|
-
target: sentinel,
|
|
196
|
-
},
|
|
197
|
-
] as unknown as IntersectionObserverEntry[]
|
|
198
|
-
// @ts-expect-error Used for testing
|
|
199
|
-
element.handleIntersection(entries)
|
|
200
|
-
|
|
201
|
-
assert.isTrue(scrollendSpy.calledOnce)
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
it('renders header cells with correct attributes and content', async () => {
|
|
205
|
-
const items = generateItems(3)
|
|
206
|
-
const element = await sortedFixture<TestItem>(items)
|
|
207
|
-
await nextFrame()
|
|
208
|
-
|
|
209
|
-
const headerCells = element.shadowRoot!.querySelectorAll('th')
|
|
210
|
-
|
|
211
|
-
const sortedColumn = `<div class="cell-content">
|
|
212
|
-
C1
|
|
213
|
-
<ui-icon
|
|
214
|
-
aria-hidden="true"
|
|
215
|
-
class="sort-icon"
|
|
216
|
-
role="presentation"
|
|
217
|
-
>
|
|
218
|
-
arrow_downward
|
|
219
|
-
</ui-icon>`
|
|
220
|
-
|
|
221
|
-
assert.dom.equal(headerCells[0].querySelector('.cell-content'), sortedColumn)
|
|
222
|
-
assert.equal(headerCells[0].dataset.sort, 'name')
|
|
223
|
-
assert.equal(headerCells[0].getAttribute('aria-sort'), 'descending')
|
|
224
|
-
|
|
225
|
-
assert.equal(headerCells[1].textContent?.trim(), 'C2')
|
|
226
|
-
assert.equal(headerCells[1].getAttribute('aria-label'), 'C2 label')
|
|
227
|
-
|
|
228
|
-
assert.equal(headerCells[2].textContent?.trim(), 'C3')
|
|
229
|
-
assert.isTrue(headerCells[2].classList.contains('my-class'))
|
|
230
|
-
|
|
231
|
-
assert.equal(headerCells[3].textContent?.trim(), 'C4')
|
|
232
|
-
assert.equal(headerCells[3].dataset.delegate, 'true')
|
|
233
|
-
|
|
234
|
-
assert.equal(headerCells[4].textContent?.trim(), 'C5')
|
|
235
|
-
assert.equal(headerCells[4].dataset.foo, 'bar')
|
|
236
|
-
|
|
237
|
-
assert.equal(headerCells[5].textContent?.trim(), 'C6')
|
|
238
|
-
assert.equal(headerCells[5].dataset.sort, 'other')
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
it('renders row cells with correct attributes and content', async () => {
|
|
242
|
-
const items = generateItems(3)
|
|
243
|
-
const element = await basicFixture<TestItem>(items)
|
|
244
|
-
await nextFrame()
|
|
245
|
-
|
|
246
|
-
const firstRow = element.shadowRoot!.querySelectorAll('tr')[1]
|
|
247
|
-
const rowCells = firstRow.querySelectorAll('td, th') as NodeListOf<HTMLElement>
|
|
248
|
-
|
|
249
|
-
assert.equal(rowCells[0].textContent?.trim(), 'R1.1')
|
|
250
|
-
assert.isTrue(rowCells[0].classList.contains('primary-cell'))
|
|
251
|
-
|
|
252
|
-
assert.equal(rowCells[1].textContent?.trim(), 'R1.2')
|
|
253
|
-
assert.equal(rowCells[1].getAttribute('aria-label'), 'R1.2 Label')
|
|
254
|
-
|
|
255
|
-
assert.equal(rowCells[2].textContent?.trim(), 'R1.3')
|
|
256
|
-
assert.isTrue(rowCells[2].classList.contains('my-class'))
|
|
257
|
-
|
|
258
|
-
assert.equal(rowCells[3].querySelector('button')?.value, 'R1.4')
|
|
259
|
-
assert.equal(rowCells[3].dataset.delegate, 'true')
|
|
260
|
-
|
|
261
|
-
assert.equal(rowCells[4].textContent?.trim(), 'R1.5')
|
|
262
|
-
assert.equal(rowCells[4].dataset.foo, 'row-bar')
|
|
263
|
-
|
|
264
|
-
assert.equal(rowCells[5].textContent?.trim(), 'R1.6')
|
|
265
|
-
})
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
describe('a11y', () => {
|
|
269
|
-
it('is accessible for basic table', async () => {
|
|
270
|
-
const items = generateItems(3)
|
|
271
|
-
const element = await basicFixture<TestItem>(items)
|
|
272
|
-
await nextFrame()
|
|
273
|
-
await assert.isAccessible(element)
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
it('is accessible for basic single selection table', async () => {
|
|
277
|
-
const items = generateItems(3)
|
|
278
|
-
const element = await singleSelectionFixture<TestItem>(items)
|
|
279
|
-
await nextFrame()
|
|
280
|
-
await assert.isAccessible(element)
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
it('is accessible for basic sorted table', async () => {
|
|
284
|
-
const items = generateItems(3)
|
|
285
|
-
const element = await sortedFixture<TestItem>(items)
|
|
286
|
-
await nextFrame()
|
|
287
|
-
await assert.isAccessible(element)
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
it('is accessible for basic multi selection table', async () => {
|
|
291
|
-
const items = generateItems(3)
|
|
292
|
-
const element = await multiSelectionFixture<TestItem>(items)
|
|
293
|
-
await nextFrame()
|
|
294
|
-
await assert.isAccessible(element)
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
it('should have correct aria attributes for single selection', async () => {
|
|
298
|
-
const items = generateItems(2)
|
|
299
|
-
const element = await singleSelectionFixture<TestItem>(items)
|
|
300
|
-
await nextFrame()
|
|
301
|
-
|
|
302
|
-
// Check table attributes
|
|
303
|
-
const table = element.shadowRoot!.querySelector('table')
|
|
304
|
-
assert.equal(table?.getAttribute('aria-multiselectable'), null)
|
|
305
|
-
|
|
306
|
-
// Simulate a selection
|
|
307
|
-
const cell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
308
|
-
cell.click()
|
|
309
|
-
await nextFrame()
|
|
310
|
-
|
|
311
|
-
// Check selected row
|
|
312
|
-
const row = element.shadowRoot!.querySelector('tr[data-index="0"]')
|
|
313
|
-
assert.equal(row?.getAttribute('aria-selected'), 'true')
|
|
314
|
-
|
|
315
|
-
await assert.isAccessible(element)
|
|
316
|
-
})
|
|
317
|
-
|
|
318
|
-
it('should have correct aria attributes for multi selection', async () => {
|
|
319
|
-
const items = generateItems(3)
|
|
320
|
-
const element = await multiSelectionFixture<TestItem>(items)
|
|
321
|
-
await nextFrame()
|
|
322
|
-
|
|
323
|
-
// Check table attributes
|
|
324
|
-
const table = element.shadowRoot!.querySelector('table')
|
|
325
|
-
assert.equal(table?.getAttribute('aria-multiselectable'), 'true')
|
|
326
|
-
|
|
327
|
-
// Simulate a selection
|
|
328
|
-
const cell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
329
|
-
cell.click()
|
|
330
|
-
await nextFrame()
|
|
331
|
-
|
|
332
|
-
// Check selected row
|
|
333
|
-
const row = element.shadowRoot!.querySelector('tr[data-index="0"]')
|
|
334
|
-
assert.equal(row?.getAttribute('aria-selected'), 'true')
|
|
335
|
-
|
|
336
|
-
// Simulate another selection
|
|
337
|
-
const cell2 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="2"]`) as HTMLElement
|
|
338
|
-
cell2.click()
|
|
339
|
-
await nextFrame()
|
|
340
|
-
|
|
341
|
-
// Check selected row
|
|
342
|
-
const row2 = element.shadowRoot!.querySelector('tr[data-index="1"]')
|
|
343
|
-
assert.equal(row2?.getAttribute('aria-selected'), 'true')
|
|
344
|
-
|
|
345
|
-
await assert.isAccessible(element)
|
|
346
|
-
})
|
|
347
|
-
|
|
348
|
-
it('should have correct aria attributes for sorting', async () => {
|
|
349
|
-
const items = generateItems(2)
|
|
350
|
-
const element = await basicFixture<TestItem>(items)
|
|
351
|
-
await nextFrame()
|
|
352
|
-
|
|
353
|
-
// Initial state: aria-sort should be "none"
|
|
354
|
-
const headerCell = element.shadowRoot!.querySelectorAll('th')[0]
|
|
355
|
-
assert.equal(headerCell.getAttribute('aria-sort'), 'none')
|
|
356
|
-
|
|
357
|
-
// Simulate a sort
|
|
358
|
-
headerCell.click()
|
|
359
|
-
await nextFrame()
|
|
360
|
-
|
|
361
|
-
// After first click, aria-sort should be "ascending"
|
|
362
|
-
assert.equal(headerCell.getAttribute('aria-sort'), 'ascending')
|
|
363
|
-
|
|
364
|
-
// Simulate another sort
|
|
365
|
-
headerCell.click()
|
|
366
|
-
await nextFrame()
|
|
367
|
-
|
|
368
|
-
// After second click, aria-sort should be "descending"
|
|
369
|
-
assert.equal(headerCell.getAttribute('aria-sort'), 'descending')
|
|
370
|
-
|
|
371
|
-
await assert.isAccessible(element)
|
|
372
|
-
})
|
|
373
|
-
|
|
374
|
-
it('should have a descriptive aria-label for the table', async () => {
|
|
375
|
-
const items = generateItems(2)
|
|
376
|
-
const element = await basicFixture<TestItem>(items)
|
|
377
|
-
element.ariaLabel = 'My Custom Table'
|
|
378
|
-
await nextFrame()
|
|
379
|
-
|
|
380
|
-
const table = element.shadowRoot!.querySelector('table')
|
|
381
|
-
assert.equal(table?.getAttribute('aria-label'), 'My Custom Table')
|
|
382
|
-
|
|
383
|
-
await assert.isAccessible(element)
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
it('should have role="row" on each table row', async () => {
|
|
387
|
-
const items = generateItems(3)
|
|
388
|
-
const element = await basicFixture<TestItem>(items)
|
|
389
|
-
await nextFrame()
|
|
390
|
-
|
|
391
|
-
const rows = element.shadowRoot!.querySelectorAll('tr')
|
|
392
|
-
rows.forEach((row) => {
|
|
393
|
-
assert.equal(row.getAttribute('role'), 'row')
|
|
394
|
-
})
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
it('should have role="columnheader" on each header cell', async () => {
|
|
398
|
-
const items = generateItems(3)
|
|
399
|
-
const element = await basicFixture<TestItem>(items)
|
|
400
|
-
await nextFrame()
|
|
401
|
-
|
|
402
|
-
const headerCells = element.shadowRoot!.querySelectorAll('thead th')
|
|
403
|
-
headerCells.forEach((headerCell) => {
|
|
404
|
-
assert.equal(headerCell.getAttribute('role'), 'columnheader')
|
|
405
|
-
assert.equal(headerCell.getAttribute('scope'), 'col')
|
|
406
|
-
})
|
|
407
|
-
})
|
|
408
|
-
|
|
409
|
-
it('should have role="gridcell" on each data cell', async () => {
|
|
410
|
-
const items = generateItems(3)
|
|
411
|
-
const element = await basicFixture<TestItem>(items)
|
|
412
|
-
await nextFrame()
|
|
413
|
-
|
|
414
|
-
const dataCells = element.shadowRoot!.querySelectorAll('tbody td, tbody th')
|
|
415
|
-
dataCells.forEach((dataCell) => {
|
|
416
|
-
assert.equal(dataCell.getAttribute('role'), 'gridcell')
|
|
417
|
-
})
|
|
418
|
-
})
|
|
419
|
-
|
|
420
|
-
it('should focus on the first header cell on init', async () => {
|
|
421
|
-
const items = generateItems(3)
|
|
422
|
-
const element = await basicFixture<TestItem>(items)
|
|
423
|
-
await nextFrame()
|
|
424
|
-
|
|
425
|
-
const firstHeaderCell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="0"]`) as HTMLElement
|
|
426
|
-
assert.equal(element.shadowRoot!.activeElement, firstHeaderCell)
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
it('should navigate with arrow keys', async () => {
|
|
430
|
-
const items = generateItems(3)
|
|
431
|
-
const element = await basicFixture<TestItem>(items)
|
|
432
|
-
await nextFrame()
|
|
433
|
-
|
|
434
|
-
const firstHeaderCell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="0"]`) as HTMLElement
|
|
435
|
-
assert.equal(element.shadowRoot!.activeElement, firstHeaderCell)
|
|
436
|
-
|
|
437
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
438
|
-
await nextFrame()
|
|
439
|
-
|
|
440
|
-
const secondHeaderCell = element.shadowRoot!.querySelector(`[data-col="1"][data-row="0"]`) as HTMLElement
|
|
441
|
-
assert.equal(element.shadowRoot!.activeElement, secondHeaderCell, 'the second cell is focused')
|
|
442
|
-
|
|
443
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
444
|
-
await nextFrame()
|
|
445
|
-
|
|
446
|
-
const firstCell = element.shadowRoot!.querySelector(`[data-col="1"][data-row="1"]`) as HTMLElement
|
|
447
|
-
assert.equal(element.shadowRoot!.activeElement, firstCell, 'the first cell in row two is focused')
|
|
448
|
-
})
|
|
449
|
-
|
|
450
|
-
it('should navigate with arrow keys and delegates the focus correctly', async () => {
|
|
451
|
-
const items = generateItems(3)
|
|
452
|
-
const element = await basicFixture<TestItem>(items)
|
|
453
|
-
await nextFrame()
|
|
454
|
-
|
|
455
|
-
const c1 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="0"]`) as HTMLElement
|
|
456
|
-
assert.equal(element.shadowRoot!.activeElement, c1, 'focuses on the first header cell')
|
|
457
|
-
|
|
458
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
459
|
-
await nextFrame() // -> r1,c0
|
|
460
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
461
|
-
await nextFrame() // -> r1,c1
|
|
462
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
463
|
-
await nextFrame() // -> r1,c2
|
|
464
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
465
|
-
await nextFrame() // -> r1,c3
|
|
466
|
-
await element.updateComplete
|
|
467
|
-
|
|
468
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
469
|
-
await nextFrame() // -> r2,c3
|
|
470
|
-
|
|
471
|
-
const button = element
|
|
472
|
-
.shadowRoot!.querySelector(`[data-col="3"][data-row="2"]`)
|
|
473
|
-
?.querySelector('button') as HTMLElement
|
|
474
|
-
assert.dom.equal(button, '<button name="r.2.4" value="R2.4" tabindex="-1">Demo</button>')
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
it('should navigate with PageUp/PageDown', async () => {
|
|
478
|
-
const items = generateItems(3)
|
|
479
|
-
const element = await basicFixture<TestItem>(items)
|
|
480
|
-
await nextFrame()
|
|
481
|
-
|
|
482
|
-
const c1 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="0"]`) as HTMLElement
|
|
483
|
-
assert.equal(element.shadowRoot!.activeElement, c1)
|
|
484
|
-
|
|
485
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
486
|
-
await nextFrame() // -> r1c0
|
|
487
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
488
|
-
await nextFrame() // -> r2c0
|
|
489
|
-
|
|
490
|
-
const c2 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="2"]`) as HTMLElement
|
|
491
|
-
assert.equal(element.shadowRoot!.activeElement, c2, 'moved to the second row')
|
|
492
|
-
|
|
493
|
-
await sendKeys({ press: 'PageUp' })
|
|
494
|
-
await nextFrame() // -> r1c0
|
|
495
|
-
|
|
496
|
-
const c3 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
497
|
-
assert.equal(element.shadowRoot!.activeElement, c3, 'focused on the first row')
|
|
498
|
-
|
|
499
|
-
await sendKeys({ press: 'PageDown' })
|
|
500
|
-
await nextFrame() // -> r3c0
|
|
501
|
-
|
|
502
|
-
const lastRowCell = element.shadowRoot!.querySelector(`[data-col="0"][data-row="3"]`) as HTMLElement
|
|
503
|
-
assert.equal(element.shadowRoot!.activeElement, lastRowCell, 'focuses on the last row')
|
|
504
|
-
})
|
|
505
|
-
|
|
506
|
-
it('should navigate with Home/End', async () => {
|
|
507
|
-
const items = generateItems(3)
|
|
508
|
-
const element = await basicFixture<TestItem>(items)
|
|
509
|
-
await nextFrame()
|
|
510
|
-
|
|
511
|
-
const c1 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="0"]`) as HTMLElement
|
|
512
|
-
assert.equal(element.shadowRoot!.activeElement, c1)
|
|
513
|
-
|
|
514
|
-
await sendKeys({ press: 'ArrowDown' })
|
|
515
|
-
await nextFrame() // -> r1c0
|
|
516
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
517
|
-
await nextFrame() // -> r1c1
|
|
518
|
-
await sendKeys({ press: 'ArrowRight' })
|
|
519
|
-
await nextFrame() // -> r1c2
|
|
520
|
-
|
|
521
|
-
const c2 = element.shadowRoot!.querySelector(`[data-col="2"][data-row="1"]`) as HTMLElement
|
|
522
|
-
assert.equal(element.shadowRoot!.activeElement, c2, 'moved to the second row, cell 2')
|
|
523
|
-
|
|
524
|
-
await sendKeys({ press: 'Home' })
|
|
525
|
-
await nextFrame() // r1c0
|
|
526
|
-
|
|
527
|
-
const c3 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
528
|
-
assert.equal(element.shadowRoot!.activeElement, c3, 'goes back to the first column')
|
|
529
|
-
|
|
530
|
-
await sendKeys({ press: 'End' })
|
|
531
|
-
await nextFrame() // r1c5
|
|
532
|
-
|
|
533
|
-
const c4 = element.shadowRoot!.querySelector(`[data-col="5"][data-row="1"]`) as HTMLElement
|
|
534
|
-
assert.equal(element.shadowRoot!.activeElement, c4, 'focuses on the last cell in the row')
|
|
535
|
-
|
|
536
|
-
await sendKeys({ press: 'Control+Home' })
|
|
537
|
-
await nextFrame() // r1c0
|
|
538
|
-
|
|
539
|
-
const c5 = element.shadowRoot!.querySelector(`[data-col="0"][data-row="1"]`) as HTMLElement
|
|
540
|
-
assert.equal(element.shadowRoot!.activeElement, c5, 'focuses on the first cell in the table')
|
|
541
|
-
})
|
|
542
|
-
})
|
|
543
|
-
|
|
544
|
-
describe('isSelected', () => {
|
|
545
|
-
it('should return true if the item is selected', async () => {
|
|
546
|
-
const items = generateItems(3)
|
|
547
|
-
const element = await multiSelectionFixture<TestItem>(items)
|
|
548
|
-
await nextFrame()
|
|
549
|
-
element.selectedItems = [items.value[1]]
|
|
550
|
-
assert.isTrue(element.isSelected(items.value[1]))
|
|
551
|
-
})
|
|
552
|
-
|
|
553
|
-
it('should return false if the item is not selected', async () => {
|
|
554
|
-
const items = generateItems(3)
|
|
555
|
-
const element = await multiSelectionFixture<TestItem>(items)
|
|
556
|
-
await nextFrame()
|
|
557
|
-
|
|
558
|
-
element.selectedItems = [items.value[1]]
|
|
559
|
-
assert.isFalse(element.isSelected(items.value[0]))
|
|
560
|
-
})
|
|
561
|
-
})
|
|
562
|
-
|
|
563
|
-
describe('infoFromEvent()', () => {
|
|
564
|
-
it('should return cell info when clicking on a td', async () => {
|
|
565
|
-
const items = generateItems(3)
|
|
566
|
-
const element = await basicFixture<TestItem>(items)
|
|
567
|
-
await nextFrame()
|
|
568
|
-
|
|
569
|
-
const cell = element.shadowRoot!.querySelector(`[data-row="2"][data-col="2"]`) as HTMLElement
|
|
570
|
-
const event = new MouseEvent('click', { bubbles: true, composed: true })
|
|
571
|
-
const spy = sinon.spy(element, 'infoFromEvent')
|
|
572
|
-
cell.dispatchEvent(event)
|
|
573
|
-
|
|
574
|
-
assert.isTrue(spy.calledOnce)
|
|
575
|
-
const info = spy.returnValues[0] as EventCellInfo
|
|
576
|
-
|
|
577
|
-
// assert.dom.equal(info.cell, cell)
|
|
578
|
-
assert.ok(info.cell, 'has the cell reference')
|
|
579
|
-
assert.equal(info?.col, 2)
|
|
580
|
-
assert.equal(info?.row, 2)
|
|
581
|
-
})
|
|
582
|
-
|
|
583
|
-
it('should return cell info when clicking on a th', async () => {
|
|
584
|
-
const items = generateItems(3)
|
|
585
|
-
const element = await basicFixture<TestItem>(items)
|
|
586
|
-
await nextFrame()
|
|
587
|
-
|
|
588
|
-
const cell = element.shadowRoot!.querySelector(`[data-row="0"][data-col="1"]`) as HTMLElement
|
|
589
|
-
const event = new MouseEvent('click', { bubbles: true, composed: true })
|
|
590
|
-
const spy = sinon.spy(element, 'infoFromEvent')
|
|
591
|
-
cell.dispatchEvent(event)
|
|
592
|
-
|
|
593
|
-
assert.isTrue(spy.calledOnce)
|
|
594
|
-
const info = spy.returnValues[0] as EventCellInfo
|
|
595
|
-
|
|
596
|
-
// assert.dom.equal(info.cell, cell)
|
|
597
|
-
assert.ok(info.cell, 'has the cell reference')
|
|
598
|
-
assert.equal(info?.row, 0)
|
|
599
|
-
assert.equal(info?.col, 1)
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
it('should return undefined when clicking outside a cell', async () => {
|
|
603
|
-
const items = generateItems(3)
|
|
604
|
-
const element = await basicFixture<TestItem>(items)
|
|
605
|
-
await nextFrame()
|
|
606
|
-
|
|
607
|
-
const event = new MouseEvent('click', { bubbles: true, composed: true })
|
|
608
|
-
const spy = sinon.spy(element, 'infoFromEvent')
|
|
609
|
-
element.dispatchEvent(event)
|
|
610
|
-
|
|
611
|
-
assert.isFalse(spy.called)
|
|
612
|
-
})
|
|
613
|
-
|
|
614
|
-
it('should return undefined when clicking on an interactive element within a cell', async () => {
|
|
615
|
-
const items = generateItems(3)
|
|
616
|
-
const element = await basicFixture<TestItem>(items)
|
|
617
|
-
await nextFrame()
|
|
618
|
-
|
|
619
|
-
const button = element.shadowRoot!.querySelector(`[data-col="3"][data-row="2"] button`) as HTMLElement
|
|
620
|
-
const event = new MouseEvent('click', { bubbles: true, composed: true })
|
|
621
|
-
const spy = sinon.spy(element, 'infoFromEvent')
|
|
622
|
-
button.dispatchEvent(event)
|
|
623
|
-
|
|
624
|
-
assert.isTrue(spy.calledOnce)
|
|
625
|
-
const info = spy.returnValues[0] as EventCellInfo | undefined
|
|
626
|
-
|
|
627
|
-
assert.isUndefined(info)
|
|
628
|
-
})
|
|
629
|
-
|
|
630
|
-
it('should return undefined when the col or row are invalid', async () => {
|
|
631
|
-
const items = generateItems(3)
|
|
632
|
-
const element = await basicFixture<TestItem>(items)
|
|
633
|
-
await nextFrame()
|
|
634
|
-
|
|
635
|
-
// Simulate an event on a malformed cell (missing data-col or data-row)
|
|
636
|
-
const fakeCell = document.createElement('td')
|
|
637
|
-
const event = new MouseEvent('click', { bubbles: true, composed: true })
|
|
638
|
-
const spy = sinon.spy(element, 'infoFromEvent')
|
|
639
|
-
const table = element.shadowRoot?.querySelector('table') as HTMLTableElement
|
|
640
|
-
table.appendChild(fakeCell)
|
|
641
|
-
fakeCell.dispatchEvent(event)
|
|
642
|
-
|
|
643
|
-
assert.isTrue(spy.calledOnce)
|
|
644
|
-
const info = spy.returnValues[0] as EventCellInfo | undefined
|
|
645
|
-
|
|
646
|
-
assert.isUndefined(info)
|
|
647
|
-
})
|
|
648
|
-
})
|
|
649
|
-
})
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { assert } from '@open-wc/testing'
|
|
2
|
-
import { Har } from 'har-format'
|
|
3
|
-
import { sortEntires } from '../../../src/elements/har/HarUtils.js'
|
|
4
|
-
|
|
5
|
-
describe('HarUtils', () => {
|
|
6
|
-
const demo1file = 'har1.har'
|
|
7
|
-
|
|
8
|
-
async function readHarFile(name: string): Promise<Har> {
|
|
9
|
-
const url = new URL(`/test/elements/har/test-data/${name}`, window.location.href).toString()
|
|
10
|
-
const response = await fetch(url)
|
|
11
|
-
return response.json()
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('sortEntires()', () => {
|
|
15
|
-
let model: Har
|
|
16
|
-
|
|
17
|
-
before(async () => {
|
|
18
|
-
model = await readHarFile(demo1file)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('sorts entries', () => {
|
|
22
|
-
const d = new Date()
|
|
23
|
-
const e1 = {
|
|
24
|
-
...model.log.entries[0],
|
|
25
|
-
id: '1',
|
|
26
|
-
startedDateTime: d.toISOString(),
|
|
27
|
-
}
|
|
28
|
-
d.setSeconds(d.getSeconds() - 10)
|
|
29
|
-
const e2 = {
|
|
30
|
-
...model.log.entries[1],
|
|
31
|
-
id: '2',
|
|
32
|
-
startedDateTime: d.toISOString(),
|
|
33
|
-
}
|
|
34
|
-
const result = sortEntires([e1, e2])
|
|
35
|
-
|
|
36
|
-
assert.equal(result[0].id, '2')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('sets the timestamp property on the items', () => {
|
|
40
|
-
const entry = { ...model.log.entries[0] }
|
|
41
|
-
const result = sortEntires([entry])
|
|
42
|
-
assert.typeOf(result[0].timestamp, 'number')
|
|
43
|
-
})
|
|
44
|
-
})
|
|
45
|
-
})
|