@looker/api-explorer 0.9.33-alpha.1522 → 0.9.33
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/CHANGELOG.md +26 -1
- package/dist/bundle.js +1 -1
- package/dist/bundle.js.LICENSE.txt +0 -9
- package/dist/bundle.js.map +1 -1
- package/e2e/diffScene.spec.ts +260 -0
- package/e2e/e2e.spec.ts +60 -29
- package/e2e/helpers.ts +9 -1
- package/jest-puppeteer.config.js +10 -0
- package/jest.config.js +25 -23
- package/lib/components/DocSource/DocSource.js +1 -1
- package/lib/components/DocSource/DocSource.js.map +1 -1
- package/lib/components/SideNav/SideNavMethods.js +7 -2
- package/lib/components/SideNav/SideNavMethods.js.map +1 -1
- package/lib/components/SideNav/SideNavTypes.js +6 -1
- package/lib/components/SideNav/SideNavTypes.js.map +1 -1
- package/lib/esm/components/DocSource/DocSource.js +2 -2
- package/lib/esm/components/DocSource/DocSource.js.map +1 -1
- package/lib/esm/components/SideNav/SideNavMethods.js +7 -2
- package/lib/esm/components/SideNav/SideNavMethods.js.map +1 -1
- package/lib/esm/components/SideNav/SideNavTypes.js +6 -1
- package/lib/esm/components/SideNav/SideNavTypes.js.map +1 -1
- package/lib/esm/scenes/DiffScene/DiffScene.js +1 -0
- package/lib/esm/scenes/DiffScene/DiffScene.js.map +1 -1
- package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js +2 -2
- package/lib/esm/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
- package/lib/scenes/DiffScene/DiffScene.js +1 -0
- package/lib/scenes/DiffScene/DiffScene.js.map +1 -1
- package/lib/scenes/DiffScene/DocDiff/DocDiff.js +2 -2
- package/lib/scenes/DiffScene/DocDiff/DocDiff.js.map +1 -1
- package/package.json +12 -12
- package/src/components/DocSource/DocSource.spec.tsx +3 -3
- package/src/components/DocSource/DocSource.tsx +3 -2
- package/src/components/SideNav/SideNavMethods.spec.tsx +49 -3
- package/src/components/SideNav/SideNavMethods.tsx +6 -2
- package/src/components/SideNav/SideNavTypes.spec.tsx +46 -10
- package/src/components/SideNav/SideNavTypes.tsx +5 -1
- package/src/scenes/DiffScene/DiffScene.tsx +1 -0
- package/src/scenes/DiffScene/DocDiff/DocDiff.spec.tsx +112 -0
- package/src/scenes/DiffScene/DocDiff/DocDiff.tsx +2 -6
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2021 Looker Data Sciences, Inc.
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
24
|
+
|
|
25
|
+
*/
|
|
26
|
+
import '@testing-library/jest-dom'
|
|
27
|
+
|
|
28
|
+
import { goToPage, BASE_URL } from './helpers'
|
|
29
|
+
|
|
30
|
+
// https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer
|
|
31
|
+
// https://github.com/puppeteer/puppeteer/blob/main/docs/api.md
|
|
32
|
+
|
|
33
|
+
jest.setTimeout(120000)
|
|
34
|
+
|
|
35
|
+
const resultCardsSelector =
|
|
36
|
+
'section#top div[class*=SpaceVertical] div[class*=Card]'
|
|
37
|
+
const baseInputSelector = 'input#listbox-input-base'
|
|
38
|
+
const compInputSelector = 'input#listbox-input-compare'
|
|
39
|
+
const globalOptionsSelector = '#modal-root [role=option] span'
|
|
40
|
+
const switchButtonSelector = '.switch-button'
|
|
41
|
+
|
|
42
|
+
describe('Diff Scene', () => {
|
|
43
|
+
beforeEach(async () => {
|
|
44
|
+
await jestPuppeteer.resetBrowser()
|
|
45
|
+
await page.setDefaultNavigationTimeout(120000)
|
|
46
|
+
})
|
|
47
|
+
it('loads the default scene (/diff/3.1)', async () => {
|
|
48
|
+
await goToPage(`${BASE_URL}/diff/3.1`)
|
|
49
|
+
const body = await page.$('body')
|
|
50
|
+
|
|
51
|
+
// "Base" input element
|
|
52
|
+
{
|
|
53
|
+
await body.click()
|
|
54
|
+
const baseInputElement = await page.$(baseInputSelector)
|
|
55
|
+
expect(baseInputElement).not.toBeNull()
|
|
56
|
+
const baseInputValue = await page.evaluate(
|
|
57
|
+
(e) => e.value,
|
|
58
|
+
baseInputElement
|
|
59
|
+
)
|
|
60
|
+
expect(baseInputValue).toMatch('3.1')
|
|
61
|
+
|
|
62
|
+
const baseOptionsOnLoad = await page.$(globalOptionsSelector)
|
|
63
|
+
expect(baseOptionsOnLoad).toBeNull()
|
|
64
|
+
|
|
65
|
+
await baseInputElement.click()
|
|
66
|
+
const baseOptionsOnClick = await page.$$(globalOptionsSelector)
|
|
67
|
+
expect(baseOptionsOnClick).not.toHaveLength(0)
|
|
68
|
+
|
|
69
|
+
await body.click()
|
|
70
|
+
const baseOptionsOnClose = await page.$(globalOptionsSelector)
|
|
71
|
+
expect(baseOptionsOnClose).toBeNull()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// "Comparison" input element
|
|
75
|
+
{
|
|
76
|
+
await body.click()
|
|
77
|
+
const compInputElement = await page.$(compInputSelector)
|
|
78
|
+
expect(compInputElement).not.toBeNull()
|
|
79
|
+
const compInputValue = await page.evaluate(
|
|
80
|
+
(e) => e.value,
|
|
81
|
+
compInputElement
|
|
82
|
+
)
|
|
83
|
+
expect(compInputValue).toEqual('')
|
|
84
|
+
|
|
85
|
+
const compOptionsOnLoad = await page.$(globalOptionsSelector)
|
|
86
|
+
expect(compOptionsOnLoad).toBeNull()
|
|
87
|
+
|
|
88
|
+
await compInputElement.click()
|
|
89
|
+
const compOptionsOnClick = await page.$$(globalOptionsSelector)
|
|
90
|
+
expect(compOptionsOnClick).not.toHaveLength(0)
|
|
91
|
+
|
|
92
|
+
await body.click()
|
|
93
|
+
const compOptionsOnClose = await page.$(globalOptionsSelector)
|
|
94
|
+
expect(compOptionsOnClose).toBeNull()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Switch button (disabled)
|
|
98
|
+
{
|
|
99
|
+
const switchButtonElement = await page.$(switchButtonSelector)
|
|
100
|
+
expect(switchButtonElement).not.toBeNull()
|
|
101
|
+
const switchButtonDisabled = await page.evaluate(
|
|
102
|
+
(e) => e.disabled,
|
|
103
|
+
switchButtonElement
|
|
104
|
+
)
|
|
105
|
+
expect(switchButtonDisabled).toEqual(true)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('loads a comparison scene (/diff/3.1/4.0) and navigates from it', async () => {
|
|
110
|
+
await goToPage(`${BASE_URL}/diff/3.1/4.0`)
|
|
111
|
+
|
|
112
|
+
// "Base" input element
|
|
113
|
+
{
|
|
114
|
+
const baseInputElement = await page.$(baseInputSelector)
|
|
115
|
+
expect(baseInputElement).not.toBeNull()
|
|
116
|
+
const baseInputValue = await page.evaluate(
|
|
117
|
+
(e) => e.value,
|
|
118
|
+
baseInputElement
|
|
119
|
+
)
|
|
120
|
+
expect(baseInputValue).toMatch('3.1')
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// "Comparison" input element
|
|
124
|
+
{
|
|
125
|
+
const compInputElement = await page.$(compInputSelector)
|
|
126
|
+
expect(compInputElement).not.toBeNull()
|
|
127
|
+
const compInputValue = await page.evaluate(
|
|
128
|
+
(e) => e.value,
|
|
129
|
+
compInputElement
|
|
130
|
+
)
|
|
131
|
+
expect(compInputValue).toMatch('4.0')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Switch button
|
|
135
|
+
{
|
|
136
|
+
const switchButtonElement = await page.$(switchButtonSelector)
|
|
137
|
+
expect(switchButtonElement).not.toBeNull()
|
|
138
|
+
const switchButtonDisabled = await page.evaluate(
|
|
139
|
+
(e) => e.disabled,
|
|
140
|
+
switchButtonElement
|
|
141
|
+
)
|
|
142
|
+
expect(switchButtonDisabled).toEqual(false)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Diff results
|
|
146
|
+
{
|
|
147
|
+
const diffResultCards = await page.$$(resultCardsSelector)
|
|
148
|
+
expect(diffResultCards).not.toHaveLength(0)
|
|
149
|
+
const page1Methods = await Promise.all(
|
|
150
|
+
diffResultCards.map((resultCard) =>
|
|
151
|
+
page.evaluate((el) => el.innerText.match(/^[a-z_]*/)[0], resultCard)
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
expect(page1Methods).toHaveLength(15)
|
|
155
|
+
expect(page1Methods).toContain('delete_board_item')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Expand a result
|
|
159
|
+
{
|
|
160
|
+
const expandedSelector =
|
|
161
|
+
resultCardsSelector + `>div[class*=Accordion2]>div[aria-expanded=true]`
|
|
162
|
+
|
|
163
|
+
// Initially not expanded
|
|
164
|
+
const expandedCardBefore = await page.$(expandedSelector)
|
|
165
|
+
expect(expandedCardBefore).toBeNull()
|
|
166
|
+
|
|
167
|
+
// Click a card
|
|
168
|
+
const firstResultCard = (await page.$$(resultCardsSelector))[0]
|
|
169
|
+
await firstResultCard.click()
|
|
170
|
+
|
|
171
|
+
// Expanded
|
|
172
|
+
const expandedCardAfter = await page.$(expandedSelector)
|
|
173
|
+
expect(expandedCardAfter).not.toBeNull()
|
|
174
|
+
|
|
175
|
+
// Find and validate method link
|
|
176
|
+
const methodLink = await page.$(`${resultCardsSelector} a[role=link]`)
|
|
177
|
+
expect(methodLink).not.toBeNull()
|
|
178
|
+
const methodText = await page.evaluate((e) => e.innerText, methodLink)
|
|
179
|
+
expect(methodText).toMatch(`delete_board_item for 4.0`)
|
|
180
|
+
|
|
181
|
+
// Click and validate destination
|
|
182
|
+
await methodLink.click()
|
|
183
|
+
await page.waitForSelector(`div[class*=MethodBadge]`, { timeout: 5000 })
|
|
184
|
+
const compUrl = page.url()
|
|
185
|
+
expect(compUrl).toEqual(`${BASE_URL}/4.0/methods/Board/delete_board_item`)
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('updates when a comparison is chosen or switched', async () => {
|
|
190
|
+
await goToPage(`${BASE_URL}/diff/3.1`)
|
|
191
|
+
|
|
192
|
+
// "Base" input element
|
|
193
|
+
const baseInputElement = await page.$(baseInputSelector)
|
|
194
|
+
expect(baseInputElement).not.toBeNull()
|
|
195
|
+
|
|
196
|
+
// "Comparison" input element
|
|
197
|
+
const compInputElement = await page.$(compInputSelector)
|
|
198
|
+
expect(compInputElement).not.toBeNull()
|
|
199
|
+
|
|
200
|
+
// Click comparison input
|
|
201
|
+
await compInputElement.click()
|
|
202
|
+
const compOptionsOnClick = await page.$$(globalOptionsSelector)
|
|
203
|
+
expect(compOptionsOnClick).not.toHaveLength(0)
|
|
204
|
+
expect(compOptionsOnClick).not.toHaveLength(1)
|
|
205
|
+
|
|
206
|
+
// Find an option containing the text 4.0
|
|
207
|
+
const option40Index = await page.$$eval(globalOptionsSelector, (els) =>
|
|
208
|
+
els.findIndex((el) => el.textContent.match(/4\.0/))
|
|
209
|
+
)
|
|
210
|
+
const option40 = compOptionsOnClick[option40Index]
|
|
211
|
+
expect(option40).not.toBeUndefined()
|
|
212
|
+
|
|
213
|
+
// Click that option
|
|
214
|
+
await option40.click()
|
|
215
|
+
await page.waitForSelector(resultCardsSelector, { timeout: 5000 })
|
|
216
|
+
|
|
217
|
+
// Check the URL
|
|
218
|
+
// Would like to do this earlier, but not sure what to wait on
|
|
219
|
+
const compUrl = page.url()
|
|
220
|
+
expect(compUrl).toEqual(`${BASE_URL}/diff/3.1/4.0`)
|
|
221
|
+
|
|
222
|
+
// Check the results
|
|
223
|
+
const diffResultCards = await page.$$(resultCardsSelector)
|
|
224
|
+
expect(diffResultCards).not.toHaveLength(0)
|
|
225
|
+
const diff31to40Page1Methods = await Promise.all(
|
|
226
|
+
diffResultCards.map((resultCard) =>
|
|
227
|
+
page.evaluate((el) => el.innerText.match(/^[a-z_]*/)[0], resultCard)
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
expect(diff31to40Page1Methods).toHaveLength(15)
|
|
232
|
+
expect(diff31to40Page1Methods).toContain('delete_board_item')
|
|
233
|
+
|
|
234
|
+
// Click the switch button
|
|
235
|
+
const switchButtonElement = await page.$(switchButtonSelector)
|
|
236
|
+
expect(switchButtonElement).not.toBeNull()
|
|
237
|
+
const switchButtonDisabled = await page.evaluate(
|
|
238
|
+
(e) => e.disabled,
|
|
239
|
+
switchButtonElement
|
|
240
|
+
)
|
|
241
|
+
expect(switchButtonDisabled).toEqual(false)
|
|
242
|
+
await switchButtonElement.click()
|
|
243
|
+
|
|
244
|
+
// A more precise timing mechanism would be better: https://github.com/puppeteer/puppeteer/issues/5328
|
|
245
|
+
await page.waitForTimeout(150)
|
|
246
|
+
|
|
247
|
+
const switchUrl = page.url()
|
|
248
|
+
expect(switchUrl).toEqual(`${BASE_URL}/diff/4.0/3.1`)
|
|
249
|
+
|
|
250
|
+
// Check the results again, even though they should be the same
|
|
251
|
+
const diff40to31Page1Methods = await Promise.all(
|
|
252
|
+
diffResultCards.map((resultCard) =>
|
|
253
|
+
page.evaluate((el) => el.innerText.match(/^[a-z_]*/)[0], resultCard)
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
expect(diff40to31Page1Methods).toHaveLength(15)
|
|
258
|
+
expect(diff40to31Page1Methods).toContain('delete_board_item')
|
|
259
|
+
})
|
|
260
|
+
})
|
package/e2e/e2e.spec.ts
CHANGED
|
@@ -25,42 +25,44 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import '@testing-library/jest-dom'
|
|
27
27
|
|
|
28
|
-
import { goToPage, pageReload } from './helpers'
|
|
28
|
+
import { goToPage, pageReload, BASE_URL } from './helpers'
|
|
29
29
|
|
|
30
30
|
// https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer
|
|
31
31
|
// https://github.com/puppeteer/puppeteer/blob/main/docs/api.md
|
|
32
32
|
|
|
33
33
|
jest.setTimeout(120000)
|
|
34
34
|
|
|
35
|
-
const BASE_URL = 'https://localhost:8080'
|
|
36
|
-
const v31 = `${BASE_URL}/3.1`
|
|
37
35
|
const v40 = `${BASE_URL}/4.0`
|
|
38
36
|
|
|
39
37
|
describe('API Explorer', () => {
|
|
40
38
|
beforeEach(async () => {
|
|
41
39
|
await jestPuppeteer.resetBrowser()
|
|
40
|
+
await page.setDefaultNavigationTimeout(120000)
|
|
42
41
|
})
|
|
43
42
|
|
|
44
43
|
describe('general', () => {
|
|
45
44
|
beforeEach(async () => {
|
|
46
|
-
await goToPage(
|
|
45
|
+
await goToPage(v40)
|
|
47
46
|
})
|
|
48
47
|
|
|
49
48
|
it('renders a method page', async () => {
|
|
50
|
-
await expect(page).toClick('h4', { text: 'Dashboard' })
|
|
51
49
|
await Promise.all([
|
|
52
50
|
page.waitForNavigation(),
|
|
53
|
-
expect(page).toClick('
|
|
51
|
+
expect(page).toClick('h4', { text: 'Dashboard' }),
|
|
52
|
+
])
|
|
53
|
+
await Promise.all([
|
|
54
|
+
page.waitForNavigation(),
|
|
55
|
+
expect(page).toClick('h3', { text: 'Get All Dashboards' }),
|
|
54
56
|
])
|
|
55
57
|
await expect(page.url()).toEqual(
|
|
56
|
-
`${
|
|
58
|
+
`${v40}/methods/Dashboard/all_dashboards`
|
|
57
59
|
)
|
|
58
60
|
|
|
59
61
|
// title
|
|
60
62
|
await expect(page).toMatchElement('h2', { text: 'Get All Dashboards' })
|
|
61
63
|
|
|
62
64
|
// markdown
|
|
63
|
-
await expect(page).toMatchElement('
|
|
65
|
+
await expect(page).toMatchElement('h3', {
|
|
64
66
|
text: 'Get information about all active dashboards',
|
|
65
67
|
})
|
|
66
68
|
|
|
@@ -115,7 +117,7 @@ describe('API Explorer', () => {
|
|
|
115
117
|
await expect(page).toMatchElement('h2', {
|
|
116
118
|
text: 'ApiAuth: API Authentication',
|
|
117
119
|
})
|
|
118
|
-
await expect(page.url()).toMatch(`${
|
|
120
|
+
await expect(page.url()).toMatch(`${v40}/methods/ApiAuth`)
|
|
119
121
|
|
|
120
122
|
await expect(page).toMatchElement(
|
|
121
123
|
'button[value="ALL"][aria-pressed=true]'
|
|
@@ -164,31 +166,35 @@ describe('API Explorer', () => {
|
|
|
164
166
|
await expect(page).toMatchElement('h3', { text: 'Kotlin Declaration' })
|
|
165
167
|
})
|
|
166
168
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
169
|
+
// This test was broken during the 4.0 GA spec changes, and needs to be fixed
|
|
170
|
+
// it('changes specs', async () => {
|
|
171
|
+
// await expect(page).toMatchElement('h2', {
|
|
172
|
+
// text: 'Looker API 4.0 Reference',
|
|
173
|
+
// })
|
|
174
|
+
// await expect(page).toClick('input[value="4.0"]')
|
|
175
|
+
// await Promise.all([
|
|
176
|
+
// page.waitForNavigation(),
|
|
177
|
+
// expect(page).toClick(
|
|
178
|
+
// 'ul[aria-label="spec selector"]>li:nth-of-type(2)'
|
|
179
|
+
// )
|
|
180
|
+
// ])
|
|
181
|
+
// //Because waitForNavigation doesn't seem to be doing what we need
|
|
182
|
+
// await page.waitForTimeout(150)
|
|
183
|
+
// await expect(page.url()).toEqual(v31)
|
|
184
|
+
// })
|
|
179
185
|
})
|
|
180
186
|
|
|
181
187
|
describe('navigation', () => {
|
|
182
188
|
it('should be able to navigate directly to a spec home', async () => {
|
|
183
|
-
await goToPage(
|
|
189
|
+
await goToPage(v40)
|
|
184
190
|
await expect(page).toMatchElement('h2', {
|
|
185
|
-
text: 'Looker API
|
|
191
|
+
text: 'Looker API 4.0 Reference',
|
|
186
192
|
})
|
|
187
|
-
await expect(page).toMatchElement('input[value="
|
|
193
|
+
await expect(page).toMatchElement('input[value="4.0"]')
|
|
188
194
|
})
|
|
189
195
|
|
|
190
196
|
it('should be able to navigate directly to a tag scene', async () => {
|
|
191
|
-
await goToPage(`${
|
|
197
|
+
await goToPage(`${v40}/methods/Dashboard`)
|
|
192
198
|
await expect(page).toMatchElement('h2', {
|
|
193
199
|
text: 'Dashboard: Manage Dashboards',
|
|
194
200
|
})
|
|
@@ -203,15 +209,40 @@ describe('API Explorer', () => {
|
|
|
203
209
|
})
|
|
204
210
|
|
|
205
211
|
it('should be able to navigate directly to a type', async () => {
|
|
206
|
-
await goToPage(`${
|
|
212
|
+
await goToPage(`${v40}/types/Query/Query`)
|
|
207
213
|
await expect(page).toMatchElement('h2', { text: 'Query' })
|
|
208
214
|
await expect(page).toMatchElement('button', { text: 'Query' })
|
|
209
215
|
})
|
|
210
216
|
})
|
|
211
217
|
|
|
218
|
+
describe('outbound navigation', () => {
|
|
219
|
+
it('should be able to navigate from a method to Github', async () => {
|
|
220
|
+
await goToPage(`${v40}/methods/Dashboard/all_dashboards`)
|
|
221
|
+
const exampleLink = await page.$(
|
|
222
|
+
'table[aria-label="SDK Examples"] a[class*=Link][target=_blank'
|
|
223
|
+
)
|
|
224
|
+
expect(exampleLink).not.toBeNull()
|
|
225
|
+
|
|
226
|
+
// Suggested/intuitive method of waiting for navigation does not seem to be working and just waits indefinitely on the target page
|
|
227
|
+
// await Promise.all([
|
|
228
|
+
// page.waitForNavigation({timeout:5000}),
|
|
229
|
+
// exampleLink.click()
|
|
230
|
+
// ])
|
|
231
|
+
await exampleLink.click()
|
|
232
|
+
await page.waitForTimeout(150)
|
|
233
|
+
|
|
234
|
+
const body = await page.$('body')
|
|
235
|
+
const codeMatch = await page.evaluate(
|
|
236
|
+
(e) => e.innerText.match('all_dashboards\\('),
|
|
237
|
+
body
|
|
238
|
+
)
|
|
239
|
+
expect(codeMatch).not.toBeNull()
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
|
|
212
243
|
describe('search', () => {
|
|
213
244
|
beforeEach(async () => {
|
|
214
|
-
await goToPage(
|
|
245
|
+
await goToPage(v40)
|
|
215
246
|
})
|
|
216
247
|
|
|
217
248
|
it('searches methods', async () => {
|
|
@@ -224,7 +255,7 @@ describe('API Explorer', () => {
|
|
|
224
255
|
await expect(page).toMatchElement('button', { text: 'Types (0)' })
|
|
225
256
|
await expect(page).toClick('a', { text: 'Get Workspace' })
|
|
226
257
|
await expect(page).toMatchElement('h2', { text: 'Get Workspace' })
|
|
227
|
-
await expect(page.url()).toEqual(`${
|
|
258
|
+
await expect(page.url()).toEqual(`${v40}/methods/Workspace/workspace`)
|
|
228
259
|
})
|
|
229
260
|
|
|
230
261
|
it('searches types', async () => {
|
|
@@ -236,7 +267,7 @@ describe('API Explorer', () => {
|
|
|
236
267
|
await expect(page).toClick('button', { text: 'Types (1)' })
|
|
237
268
|
await expect(page).toClick('a', { text: 'WriteTheme' })
|
|
238
269
|
await expect(page).toMatchElement('h2', { text: 'WriteTheme' })
|
|
239
|
-
await expect(page.url()).toEqual(`${
|
|
270
|
+
await expect(page.url()).toEqual(`${v40}/types/Theme/WriteTheme`)
|
|
240
271
|
})
|
|
241
272
|
})
|
|
242
273
|
})
|
package/e2e/helpers.ts
CHANGED
|
@@ -23,6 +23,14 @@
|
|
|
23
23
|
SOFTWARE.
|
|
24
24
|
|
|
25
25
|
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Constants
|
|
29
|
+
*/
|
|
30
|
+
export const BASE_URL = 'https://localhost:8080'
|
|
31
|
+
export const v31Url = `${BASE_URL}/3.1`
|
|
32
|
+
export const v40Url = `${BASE_URL}/4.0`
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* Reloads the page, waiting for for the DomContentLoaded event before resolving
|
|
28
36
|
*/
|
|
@@ -37,7 +45,7 @@ export const pageReload = async (): Promise<void> => {
|
|
|
37
45
|
export const goToPage = async (url: string): Promise<void> => {
|
|
38
46
|
await page.goto(url, {
|
|
39
47
|
waitUntil: ['domcontentloaded', 'networkidle0'],
|
|
40
|
-
timeout:
|
|
48
|
+
timeout: 120000,
|
|
41
49
|
})
|
|
42
50
|
}
|
|
43
51
|
|
package/jest-puppeteer.config.js
CHANGED
|
@@ -23,9 +23,19 @@
|
|
|
23
23
|
SOFTWARE.
|
|
24
24
|
|
|
25
25
|
*/
|
|
26
|
+
|
|
27
|
+
const base = require('../../jest.config')
|
|
26
28
|
module.exports = {
|
|
29
|
+
...base,
|
|
30
|
+
rootDir: '../..',
|
|
31
|
+
preset: 'jest-puppeteer',
|
|
32
|
+
setupFilesAfterEnv: ['expect-puppeteer'],
|
|
27
33
|
launch: {
|
|
34
|
+
// `headless:false` and `slowMo:250` can be useful for "test-watch" usage
|
|
28
35
|
headless: true,
|
|
36
|
+
// slowMo: 250,
|
|
37
|
+
|
|
38
|
+
// Other launch settings constant for both dev and testing usage
|
|
29
39
|
args: ['--ignore-certificate-errors'],
|
|
30
40
|
product: 'chrome',
|
|
31
41
|
devtools: true,
|
package/jest.config.js
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
/*
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2022 Looker Data Sciences, Inc.
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
24
|
+
|
|
23
25
|
*/
|
|
24
26
|
const base = require('../../jest.config')
|
|
25
27
|
const packageName = require('./package.json').name.split('/')[1]
|
|
@@ -29,7 +31,7 @@ module.exports = {
|
|
|
29
31
|
displayName: packageName,
|
|
30
32
|
name: packageName,
|
|
31
33
|
rootDir: '../..',
|
|
32
|
-
|
|
33
|
-
setupFilesAfterEnv: ['expect-puppeteer'],
|
|
34
|
+
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
|
|
34
35
|
testMatch: [`<rootDir>/packages/${packageName}/**/*.(spec|test).(ts|js)?(x)`],
|
|
36
|
+
testEnvironment: 'jsdom',
|
|
35
37
|
}
|
|
@@ -33,7 +33,7 @@ var DocSource = _ref => {
|
|
|
33
33
|
({
|
|
34
34
|
declaration,
|
|
35
35
|
link: sourceLink
|
|
36
|
-
} = (0, _sdkCodegen.findDeclaration)(declarations, method === null || method === void 0 ? void 0 : method.id, type === null || type === void 0 ? void 0 : type.name));
|
|
36
|
+
} = (0, _sdkCodegen.findDeclaration)(declarations, method === null || method === void 0 ? void 0 : method.id, type === null || type === void 0 ? void 0 : type.name, _sdkCodegen.codeSearchLink));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return _react.default.createElement(_react.default.Fragment, null, sourceLink && declaration && _react.default.createElement(_components.Tooltip, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DocSource/DocSource.tsx"],"names":["DocSource","method","type","declarations","selectDeclarationsLode","sourceLink","declaration","link","id","name","sourceFile","line"],"mappings":";;;;;;;AA0BA;;AAEA;;AACA;;AACA;;AACA;;AAEA;;;;AAOO,IAAMA,SAA6B,GAAG,QAAsB;AAAA,MAArB;AAAEC,IAAAA,MAAF;AAAUC,IAAAA;AAAV,GAAqB;AACjE,MAAMC,YAAY,GAAG,6BAAYC,6BAAZ,CAArB;AACA,MAAIC,UAAJ;AACA,MAAIC,WAAJ;;AACA,MAAIH,YAAJ,EAAkB;AAChB;AAAC,KAAC;AAAEG,MAAAA,WAAF;AAAeC,MAAAA,IAAI,EAAEF;AAArB,QAAoC,iCACpCF,YADoC,EAEpCF,MAFoC,aAEpCA,MAFoC,uBAEpCA,MAAM,CAAEO,EAF4B,EAGpCN,IAHoC,aAGpCA,IAHoC,uBAGpCA,IAAI,CAAEO,IAH8B,CAArC;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DocSource/DocSource.tsx"],"names":["DocSource","method","type","declarations","selectDeclarationsLode","sourceLink","declaration","link","id","name","codeSearchLink","sourceFile","line"],"mappings":";;;;;;;AA0BA;;AAEA;;AACA;;AACA;;AACA;;AAEA;;;;AAOO,IAAMA,SAA6B,GAAG,QAAsB;AAAA,MAArB;AAAEC,IAAAA,MAAF;AAAUC,IAAAA;AAAV,GAAqB;AACjE,MAAMC,YAAY,GAAG,6BAAYC,6BAAZ,CAArB;AACA,MAAIC,UAAJ;AACA,MAAIC,WAAJ;;AACA,MAAIH,YAAJ,EAAkB;AAChB;AAAC,KAAC;AAAEG,MAAAA,WAAF;AAAeC,MAAAA,IAAI,EAAEF;AAArB,QAAoC,iCACpCF,YADoC,EAEpCF,MAFoC,aAEpCA,MAFoC,uBAEpCA,MAAM,CAAEO,EAF4B,EAGpCN,IAHoC,aAGpCA,IAHoC,uBAGpCA,IAAI,CAAEO,IAH8B,EAIpCC,0BAJoC,CAArC;AAMF;;AAED,SACE,4DACGL,UAAU,IAAIC,WAAd,IACC,6BAAC,mBAAD;AACE,IAAA,OAAO,YAAKA,WAAW,CAACK,UAAjB,eAAgCL,WAAW,CAACM,IAA5C,CADT;AAEE,IAAA,KAAK,EAAC;AAFR,KAIE,6BAAC,gBAAD;AAAM,IAAA,IAAI,EAAEP,UAAZ;AAAwB,IAAA,MAAM,EAAC;AAA/B,KACE,6BAAC,gBAAD;AAAM,IAAA,IAAI,EAAE,6BAAC,sBAAD;AAAZ,IADF,CAJF,CAFJ,CADF;AAcD,CA3BM","sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\nimport type { FC } from 'react'\nimport React from 'react'\nimport type { IMethod, IType } from '@looker/sdk-codegen'\nimport { codeSearchLink, findDeclaration } from '@looker/sdk-codegen'\nimport { Icon, Link, Tooltip } from '@looker/components'\nimport { IdeFileDocument } from '@looker/icons'\nimport { useSelector } from 'react-redux'\n\nimport { selectDeclarationsLode } from '../../state'\n\ninterface DocSourceProps {\n method?: IMethod\n type?: IType\n}\n\nexport const DocSource: FC<DocSourceProps> = ({ method, type }) => {\n const declarations = useSelector(selectDeclarationsLode)\n let sourceLink\n let declaration\n if (declarations) {\n ;({ declaration, link: sourceLink } = findDeclaration(\n declarations,\n method?.id,\n type?.name,\n codeSearchLink\n ))\n }\n\n return (\n <>\n {sourceLink && declaration && (\n <Tooltip\n content={`${declaration.sourceFile}#L${declaration.line}`}\n width=\"none\"\n >\n <Link href={sourceLink} target=\"_blank\">\n <Icon icon={<IdeFileDocument />} />\n </Link>\n </Tooltip>\n )}\n </>\n )\n}\n"],"file":"DocSource.js"}
|
|
@@ -44,13 +44,18 @@ var SideNavMethods = (0, _styledComponents.default)(_ref => {
|
|
|
44
44
|
var _isOpen = !isOpen;
|
|
45
45
|
|
|
46
46
|
setIsOpen(_isOpen);
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
if (_isOpen) {
|
|
49
|
+
history.push("/".concat(specKey, "/methods/").concat(tag));
|
|
50
|
+
} else {
|
|
51
|
+
history.push("/".concat(specKey, "/methods"));
|
|
52
|
+
}
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
(0, _react.useEffect)(() => {
|
|
51
56
|
var status = match ? defaultOpen || match.params.methodTag === tag : defaultOpen;
|
|
52
57
|
setIsOpen(status);
|
|
53
|
-
}, [defaultOpen
|
|
58
|
+
}, [defaultOpen]);
|
|
54
59
|
return _react.default.createElement(_components.Accordion2, {
|
|
55
60
|
isOpen: isOpen,
|
|
56
61
|
toggleOpen: handleOpen,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/SideNav/SideNavMethods.tsx"],"names":["SideNavMethods","className","methods","tag","specKey","defaultOpen","searchPattern","selectSearchPattern","match","isOpen","setIsOpen","history","handleOpen","_isOpen","push","status","params","methodTag","Object","values","map","method","name","summary","theme","fonts","brand","colors","key","fontWeights","semiBold","ui2","space","xxsmall","ui1","Link","radii","medium","xsmall"],"mappings":";;;;;;;AA0BA;;AACA;;AACA;;AAEA;;AACA;;AAEA;;AACA;;AACA;;;;;;;;AAUO,IAAMA,cAAc,GAAG,+BAC5B,QAA6E;AAAA,MAA5E;AAAEC,IAAAA,SAAF;AAAaC,IAAAA,OAAb;AAAsBC,IAAAA,GAAtB;AAA2BC,IAAAA,OAA3B;AAAoCC,IAAAA,WAAW,GAAG;AAAlD,GAA4E;AAC3E,MAAMC,aAAa,GAAG,6BAAYC,0BAAZ,CAAtB;AACA,MAAMC,KAAK,GAAG,+EAAd;AAGA,MAAM,CAACC,MAAD,EAASC,SAAT,IAAsB,qBAASL,WAAT,CAA5B;AACA,MAAMM,OAAO,GAAG,iCAAhB;;AAEA,MAAMC,UAAU,GAAG,MAAM;AACvB,QAAMC,OAAO,GAAG,CAACJ,MAAjB;;AACAC,IAAAA,SAAS,CAACG,OAAD,CAAT
|
|
1
|
+
{"version":3,"sources":["../../../src/components/SideNav/SideNavMethods.tsx"],"names":["SideNavMethods","className","methods","tag","specKey","defaultOpen","searchPattern","selectSearchPattern","match","isOpen","setIsOpen","history","handleOpen","_isOpen","push","status","params","methodTag","Object","values","map","method","name","summary","theme","fonts","brand","colors","key","fontWeights","semiBold","ui2","space","xxsmall","ui1","Link","radii","medium","xsmall"],"mappings":"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","sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport React, { useEffect, useState } from 'react'\nimport styled from 'styled-components'\nimport { Accordion2, Heading } from '@looker/components'\nimport type { MethodList } from '@looker/sdk-codegen'\nimport { useSelector } from 'react-redux'\nimport { useHistory, useRouteMatch } from 'react-router-dom'\n\nimport { Link } from '../Link'\nimport { buildMethodPath, highlightHTML } from '../../utils'\nimport { selectSearchPattern } from '../../state'\n\ninterface MethodsProps {\n methods: MethodList\n tag: string\n specKey: string\n className?: string\n defaultOpen?: boolean\n}\n\nexport const SideNavMethods = styled(\n ({ className, methods, tag, specKey, defaultOpen = false }: MethodsProps) => {\n const searchPattern = useSelector(selectSearchPattern)\n const match = useRouteMatch<{ methodTag: string }>(\n `/:specKey/methods/:methodTag/:methodName?`\n )\n const [isOpen, setIsOpen] = useState(defaultOpen)\n const history = useHistory()\n\n const handleOpen = () => {\n const _isOpen = !isOpen\n setIsOpen(_isOpen)\n if (_isOpen) {\n history.push(`/${specKey}/methods/${tag}`)\n } else {\n history.push(`/${specKey}/methods`)\n }\n }\n\n useEffect(() => {\n const status = match\n ? defaultOpen || match.params.methodTag === tag\n : defaultOpen\n setIsOpen(status)\n }, [defaultOpen])\n\n /* TODO: Fix highlighting. It is applied but it is somehow being overridden */\n return (\n <Accordion2\n isOpen={isOpen}\n toggleOpen={handleOpen}\n className={className}\n label={\n <Heading as=\"h4\" fontSize=\"small\" py=\"xsmall\">\n {highlightHTML(searchPattern, tag)}\n </Heading>\n }\n >\n <ul>\n {Object.values(methods).map((method) => (\n <li key={method.name}>\n <Link to={`${buildMethodPath(specKey, tag, method.name)}`}>\n {highlightHTML(searchPattern, method.summary)}\n </Link>\n </li>\n ))}\n </ul>\n </Accordion2>\n )\n }\n)`\n font-family: ${({ theme }) => theme.fonts.brand};\n\n [aria-controls]:hover,\n [aria-expanded='true'] {\n h4,\n svg {\n color: ${({ theme }) => theme.colors.key};\n }\n }\n\n [aria-expanded='true'] h4 {\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n }\n\n ul {\n border-left: dashed 1px ${({ theme }) => theme.colors.ui2};\n list-style: none;\n margin: 0;\n padding: 0;\n padding-left: ${({ theme }) => theme.space.xxsmall};\n padding-top: ${({ theme }) => theme.space.xxsmall};\n }\n\n [aria-current] {\n background: ${({ theme }) => theme.colors.ui1};\n font-weight: ${({ theme }) => theme.fontWeights.semiBold};\n }\n\n ${Link} {\n border-radius: ${({ theme }) => theme.radii.medium};\n display: block;\n overflow: hidden;\n padding: ${({ theme }) => theme.space.xsmall};\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &:hover,\n &:focus,\n &.active {\n background: ${({ theme }) => theme.colors.ui1};\n }\n }\n`\n"],"file":"SideNavMethods.js"}
|
|
@@ -44,7 +44,12 @@ var SideNavTypes = (0, _styledComponents.default)(_ref => {
|
|
|
44
44
|
var _isOpen = !isOpen;
|
|
45
45
|
|
|
46
46
|
setIsOpen(_isOpen);
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
if (_isOpen) {
|
|
49
|
+
history.push("/".concat(specKey, "/types/").concat(tag));
|
|
50
|
+
} else {
|
|
51
|
+
history.push("/".concat(specKey, "/types"));
|
|
52
|
+
}
|
|
48
53
|
};
|
|
49
54
|
|
|
50
55
|
(0, _react.useEffect)(() => {
|