construct-hub-webapp 0.1.1119 → 0.1.1121
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/README.md +1 -1
- package/cypress/e2e/faq.cy.ts +9 -0
- package/cypress/e2e/footer.cy.ts +28 -0
- package/cypress/e2e/header.cy.ts +125 -0
- package/cypress/e2e/home.cy.ts +259 -0
- package/cypress/e2e/package-page.cy.ts +170 -0
- package/cypress/e2e/search.cy.ts +214 -0
- package/cypress/e2e/site-terms.cy.ts +9 -0
- package/cypress/e2e/xss.cy.ts +127 -0
- package/cypress/support/e2e.ts +11 -0
- package/cypress.config.ts +19 -0
- package/package.json +9 -9
- package/cypress.json +0 -14
package/README.md
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import testIds from "components/Footer/testIds";
|
|
2
|
+
|
|
3
|
+
const footerTests = (viewport?: Cypress.ViewportPreset) => {
|
|
4
|
+
before(() => {
|
|
5
|
+
cy.visit("/terms");
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
if (viewport) {
|
|
10
|
+
cy.viewport(viewport);
|
|
11
|
+
}
|
|
12
|
+
cy.checkFooterVisibility();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("has expected elements", () => {
|
|
16
|
+
Object.values(testIds).forEach((testId) => {
|
|
17
|
+
cy.getByDataTest(testId).should("be.visible");
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe("Footer", () => {
|
|
23
|
+
describe("Desktop", footerTests);
|
|
24
|
+
|
|
25
|
+
describe("Tablet", () => footerTests("ipad-2"));
|
|
26
|
+
|
|
27
|
+
describe("Mobile", () => footerTests("iphone-xr"));
|
|
28
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import headerTestIds from "components/Header/testIds";
|
|
2
|
+
import searchModalTestIds from "components/SearchModal/testIds";
|
|
3
|
+
import searchBar from "components/SearchBar/testIds";
|
|
4
|
+
|
|
5
|
+
const checkBaseElements = () => {
|
|
6
|
+
cy.getByDataTest(headerTestIds.title).should("be.visible");
|
|
7
|
+
cy.getByDataTest(headerTestIds.gettingStartedTrigger).should("be.visible");
|
|
8
|
+
cy.getByDataTest(headerTestIds.documentationTrigger).should("be.visible");
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const checkMenuInteractions = () => {
|
|
12
|
+
cy.getByDataTest(headerTestIds.gettingStartedTrigger)
|
|
13
|
+
.should("be.visible")
|
|
14
|
+
.click();
|
|
15
|
+
|
|
16
|
+
cy.getByDataTest(headerTestIds.gettingStartedMenu).should("be.visible");
|
|
17
|
+
cy.getByDataTest(headerTestIds.gettingStartedTrigger)
|
|
18
|
+
.should("be.visible")
|
|
19
|
+
.click(); // To close
|
|
20
|
+
|
|
21
|
+
cy.getByDataTest(headerTestIds.documentationTrigger).should("be.visible").click();
|
|
22
|
+
cy.getByDataTest(headerTestIds.documentationMenu).should("be.visible");
|
|
23
|
+
cy.getByDataTest(headerTestIds.documentationTrigger).should("be.visible").click(); // To close
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const checkMobileBaseElements = () => {
|
|
27
|
+
cy.getByDataTest(headerTestIds.title).should("be.visible");
|
|
28
|
+
cy.getByDataTest(headerTestIds.navOpen).should("be.visible");
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe("Header", () => {
|
|
32
|
+
describe("Desktop - Without Search", () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
cy.visit("/");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("has title, Getting Started, and Resources", checkBaseElements);
|
|
38
|
+
it("can open GettingStarted and Resources menus", checkMenuInteractions);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("Desktop - With Search", () => {
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
// Visible on all routes except / & /search
|
|
44
|
+
cy.visit("/faq");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("has title, Getting Started, Resources, and SearchBar", () => {
|
|
48
|
+
checkBaseElements();
|
|
49
|
+
cy.getByDataTest(headerTestIds.searchInput).should("be.visible");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("has search capabilities from header", () => {
|
|
53
|
+
cy.getByDataTest(headerTestIds.searchInput).should("be.visible");
|
|
54
|
+
|
|
55
|
+
cy.getByDataTest(searchBar.input).should("be.visible").click();
|
|
56
|
+
|
|
57
|
+
cy.getByDataTest(searchBar.overlay)
|
|
58
|
+
.should("be.visible")
|
|
59
|
+
.click()
|
|
60
|
+
.should("not.be.visible");
|
|
61
|
+
|
|
62
|
+
cy.getByDataTest(searchBar.input).type("@aws-cdk");
|
|
63
|
+
|
|
64
|
+
cy.getByDataTest(searchBar.overlay).should("be.visible");
|
|
65
|
+
cy.getByDataTest(searchBar.suggestionsList).should("be.visible");
|
|
66
|
+
cy.getByDataTest(searchBar.suggestion).should("have.length", 5);
|
|
67
|
+
|
|
68
|
+
cy.get("body").type("{esc}");
|
|
69
|
+
cy.getByDataTest(searchBar.overlay).should("not.be.visible");
|
|
70
|
+
cy.getByDataTest(searchBar.suggestionsList).should("not.exist");
|
|
71
|
+
|
|
72
|
+
cy.getByDataTest(searchBar.input).type("{enter}");
|
|
73
|
+
cy.url().should("include", "/search");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("Mobile - Without Search", () => {
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
cy.viewport("iphone-xr");
|
|
80
|
+
cy.visit("/");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("has title and button to open nav", checkMobileBaseElements);
|
|
84
|
+
|
|
85
|
+
it("nav has dropdowns", () => {
|
|
86
|
+
cy.getByDataTest(headerTestIds.navOpen).should("be.visible").click();
|
|
87
|
+
cy.getByDataTest(headerTestIds.mobileNav)
|
|
88
|
+
.should("be.visible")
|
|
89
|
+
.within(() => {
|
|
90
|
+
cy.getByDataTest(headerTestIds.gettingStartedMenu).should(
|
|
91
|
+
"be.visible"
|
|
92
|
+
);
|
|
93
|
+
cy.getByDataTest(headerTestIds.documentationMenu).should("be.visible");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe("Mobile - With Search", () => {
|
|
99
|
+
beforeEach(() => {
|
|
100
|
+
cy.viewport("iphone-xr");
|
|
101
|
+
cy.visit("/faq");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("has base elements and search icon", () => {
|
|
105
|
+
checkMobileBaseElements();
|
|
106
|
+
cy.getByDataTest(headerTestIds.searchIcon).should("be.visible");
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("opens search modal when search icon is clicked", () => {
|
|
110
|
+
cy.getByDataTest(headerTestIds.searchIcon).should("be.visible").click();
|
|
111
|
+
cy.getByDataTest(searchModalTestIds.container).should("be.visible");
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("has search functionality from search modal", () => {
|
|
115
|
+
cy.getByDataTest(headerTestIds.searchIcon).should("be.visible").click();
|
|
116
|
+
|
|
117
|
+
cy.getByDataTest(searchModalTestIds.container).within(() => {
|
|
118
|
+
cy.getByDataTest(searchBar.input)
|
|
119
|
+
.type("@aws-cdk{enter}")
|
|
120
|
+
.url()
|
|
121
|
+
.should("include", "/search");
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import searchBar from "components/SearchBar/testIds";
|
|
2
|
+
import home from "views/Home/testIds";
|
|
3
|
+
import { getSearchPath } from "util/url";
|
|
4
|
+
import { CDKType, CDKTYPE_RENDER_MAP } from "constants/constructs";
|
|
5
|
+
import {
|
|
6
|
+
Language,
|
|
7
|
+
LANGUAGE_NAME_MAP,
|
|
8
|
+
TEMP_SUPPORTED_LANGUAGES,
|
|
9
|
+
} from "constants/languages";
|
|
10
|
+
import packageCard from "components/PackageCard/testIds";
|
|
11
|
+
import { CatalogSearchSort } from "api/catalog-search/constants";
|
|
12
|
+
|
|
13
|
+
describe("Home (Redesign / WIP)", () => {
|
|
14
|
+
describe("Hero Section", () => {
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
cy.visit("/");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("has heading and subtitle", () => {
|
|
20
|
+
cy.getByDataTest(home.heroHeader).should("be.visible");
|
|
21
|
+
cy.getByDataTest(home.heroSubtitle).should("be.visible");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("has search capabilities from home page", () => {
|
|
25
|
+
cy.getByDataTest(home.page).within(() => {
|
|
26
|
+
cy.getByDataTest(searchBar.input)
|
|
27
|
+
.should("be.visible")
|
|
28
|
+
.type("@aws-cdk", { force: true });
|
|
29
|
+
cy.getByDataTest(searchBar.overlay).should("be.visible");
|
|
30
|
+
cy.getByDataTest(searchBar.suggestionsList).should("be.visible");
|
|
31
|
+
cy.getByDataTest(searchBar.suggestion).should("have.length", 5);
|
|
32
|
+
cy.getByDataTest(searchBar.input)
|
|
33
|
+
.type("{enter}")
|
|
34
|
+
.url()
|
|
35
|
+
.should("include", "/search");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("Informational Section", () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
cy.visit("/");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("has expected sections and content", () => {
|
|
46
|
+
cy.getByDataTest(home.infoContainer)
|
|
47
|
+
.should("be.visible")
|
|
48
|
+
.within(() => {
|
|
49
|
+
cy.getByDataTest(home.infoSection)
|
|
50
|
+
.should("have.length", 3)
|
|
51
|
+
.each((el) => {
|
|
52
|
+
cy.wrap(el).within(() => {
|
|
53
|
+
cy.getByDataTest(home.infoSectionHeading).should("be.visible");
|
|
54
|
+
cy.getByDataTest(home.infoSectionDescription).should(
|
|
55
|
+
"be.visible"
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("has cdkType icon links with search urls", () => {
|
|
63
|
+
cy.getByDataTest(home.infoSection)
|
|
64
|
+
.first()
|
|
65
|
+
.within(() => {
|
|
66
|
+
cy.getByDataTest(home.infoSectionIcon).each((el, index) => {
|
|
67
|
+
const cdkType = [CDKType.awscdk, CDKType.cdk8s, CDKType.cdktf][
|
|
68
|
+
index
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
cy.wrap(el)
|
|
72
|
+
.should("have.text", CDKTYPE_RENDER_MAP[cdkType].name)
|
|
73
|
+
.should(
|
|
74
|
+
"have.attr",
|
|
75
|
+
"href",
|
|
76
|
+
getSearchPath({
|
|
77
|
+
cdkType,
|
|
78
|
+
sort: CatalogSearchSort.DownloadsDesc,
|
|
79
|
+
})
|
|
80
|
+
)
|
|
81
|
+
.find("img")
|
|
82
|
+
.should("have.attr", "src", CDKTYPE_RENDER_MAP[cdkType].imgsrc);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("has language icon links with search urls", () => {
|
|
88
|
+
cy.getByDataTest(home.infoSection)
|
|
89
|
+
.eq(1)
|
|
90
|
+
.within(() => {
|
|
91
|
+
cy.getByDataTest(home.infoSectionIcon).each((el, index) => {
|
|
92
|
+
const language = Object.keys(LANGUAGE_NAME_MAP).filter((l) =>
|
|
93
|
+
TEMP_SUPPORTED_LANGUAGES.has(l as Language)
|
|
94
|
+
)[index] as Language;
|
|
95
|
+
|
|
96
|
+
cy.wrap(el)
|
|
97
|
+
.should("have.text", LANGUAGE_NAME_MAP[language])
|
|
98
|
+
.should(
|
|
99
|
+
"have.attr",
|
|
100
|
+
"href",
|
|
101
|
+
getSearchPath({
|
|
102
|
+
languages: [language],
|
|
103
|
+
sort: CatalogSearchSort.DownloadsDesc,
|
|
104
|
+
})
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe("Featured Section", () => {
|
|
112
|
+
it("has a header and 4 cards", () => {
|
|
113
|
+
cy.visit("/");
|
|
114
|
+
cy.getByDataTest(home.featuredContainer)
|
|
115
|
+
.should("be.visible")
|
|
116
|
+
.within(() => {
|
|
117
|
+
cy.getByDataTest(home.featuredHeader).should("be.visible");
|
|
118
|
+
cy.getByDataTest(home.featuredGrid)
|
|
119
|
+
.should("be.visible")
|
|
120
|
+
.within(() => {
|
|
121
|
+
cy.getByDataTest(packageCard.wideContainer).should(
|
|
122
|
+
"have.length",
|
|
123
|
+
4
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("shows recently updated if no content is featured", () => {
|
|
130
|
+
cy.visitWithConfig("/", {
|
|
131
|
+
featuredPackages: undefined,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
cy.getByDataTest(home.featuredContainer).within(() => {
|
|
135
|
+
cy.getByDataTest(home.featuredHeader).should(
|
|
136
|
+
"have.text",
|
|
137
|
+
"Recently updated"
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("shows featured content if config provides featured content", () => {
|
|
143
|
+
const featuredPackages = {
|
|
144
|
+
sections: [
|
|
145
|
+
{
|
|
146
|
+
name: "Featured packages",
|
|
147
|
+
showPackages: [
|
|
148
|
+
{
|
|
149
|
+
name: "@aws-cdk/aws-s3",
|
|
150
|
+
comment: "One of the most popular AWS CDK libraries!",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "@aws-cdk/aws-lambda",
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "@aws-cdk/aws-iam",
|
|
157
|
+
comment:
|
|
158
|
+
"Secure your constructs with safe and manageable permission boundaries.",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "@aws-cdk/pipelines",
|
|
162
|
+
comment:
|
|
163
|
+
"The most recently released L3 construct library from the CDK team!",
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: "Recently updated",
|
|
169
|
+
showLastUpdated: 5,
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
cy.visitWithConfig("/", {
|
|
175
|
+
featuredPackages,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
cy.getByDataTest(home.featuredContainer).within(() => {
|
|
179
|
+
cy.getByDataTest(home.featuredHeader).should(
|
|
180
|
+
"have.text",
|
|
181
|
+
"Featured packages"
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
cy.getByDataTest(packageCard.title).each((title, index) => {
|
|
185
|
+
const expectedName =
|
|
186
|
+
featuredPackages.sections[0].showPackages[index].name;
|
|
187
|
+
|
|
188
|
+
cy.wrap(title).should("have.text", expectedName);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe("CDK Type Section", () => {
|
|
195
|
+
it("has heading, description, 3 tabs, 4 cards, and a see all button", () => {
|
|
196
|
+
cy.visit("/");
|
|
197
|
+
|
|
198
|
+
cy.getByDataTest(home.cdkTypeSection).within(() => {
|
|
199
|
+
cy.getByDataTest(home.cdkTypeSectionHeading).should("be.visible");
|
|
200
|
+
cy.getByDataTest(home.cdkTypeSectionDescription).should("be.visible");
|
|
201
|
+
|
|
202
|
+
cy.getByDataTest(home.cdkTypeTab).should("have.length", 3);
|
|
203
|
+
|
|
204
|
+
cy.getByDataTest(home.packageGrid)
|
|
205
|
+
.first()
|
|
206
|
+
.within(() => {
|
|
207
|
+
cy.getByDataTest(packageCard.wideContainer).should(
|
|
208
|
+
"have.length",
|
|
209
|
+
4
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
cy.getByDataTest(home.cdkTypeSeeAllButton).should("be.visible");
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("reveals different cards for respective tabs", () => {
|
|
218
|
+
cy.visit("/");
|
|
219
|
+
|
|
220
|
+
cy.getByDataTest(home.cdkTypeSection).within(() => {
|
|
221
|
+
cy.getByDataTest(home.cdkTypeTab).each((tab, index) => {
|
|
222
|
+
const tabName: string = ["Community", "AWS", "HashiCorp"][index];
|
|
223
|
+
|
|
224
|
+
cy.wrap(tab).click();
|
|
225
|
+
|
|
226
|
+
cy.wrap(tab).should("have.attr", "data-value", tabName);
|
|
227
|
+
|
|
228
|
+
// Verify current tab's package grid is visible and others are not
|
|
229
|
+
cy.getByDataTest(home.packageGrid).each((grid, gridIndex) => {
|
|
230
|
+
cy.wrap(grid).should(
|
|
231
|
+
index === gridIndex ? "be.visible" : "not.be.visible"
|
|
232
|
+
);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("has a see all button which opens the correct search url", () => {
|
|
239
|
+
cy.visit("/");
|
|
240
|
+
|
|
241
|
+
const testSeeAll = (tagName: string, index: number) => {
|
|
242
|
+
cy.getByDataTest(home.cdkTypeTab).eq(index).click();
|
|
243
|
+
|
|
244
|
+
cy.getByDataTest(home.cdkTypeSeeAllButton)
|
|
245
|
+
.eq(index)
|
|
246
|
+
.should(
|
|
247
|
+
"have.attr",
|
|
248
|
+
"href",
|
|
249
|
+
getSearchPath({
|
|
250
|
+
tags: [tagName],
|
|
251
|
+
sort: CatalogSearchSort.DownloadsDesc,
|
|
252
|
+
})
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
["community", "aws-published", "hashicorp-published"].forEach(testSeeAll);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { getPackagePath } from "util/url";
|
|
2
|
+
import header from "components/Header/testIds";
|
|
3
|
+
import packagePage from "views/Package/testIds";
|
|
4
|
+
import markdown from "components/Markdown/testIds";
|
|
5
|
+
import assemblyFixture from "../fixtures/assembly-constructs@3.3.161.json";
|
|
6
|
+
import versionsFixture from "../fixtures/all-versions.json";
|
|
7
|
+
import { sanitizeVersion } from "api/package/util";
|
|
8
|
+
import { Language } from "constants/languages";
|
|
9
|
+
import { CONSTRUCT_HUB_REPO_URL } from "../../src/constants/links";
|
|
10
|
+
import semver from "semver";
|
|
11
|
+
|
|
12
|
+
describe("Package Page", () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
cy.intercept("**/constructs/v3.3.161/assembly.json", async (req) => {
|
|
15
|
+
req.reply({
|
|
16
|
+
fixture: "assembly-constructs@3.3.161",
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
cy.intercept("**/constructs/v3.3.161/metadata.json", async (req) => {
|
|
21
|
+
req.reply({
|
|
22
|
+
fixture: "metadata-constructs@3.3.161",
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
cy.intercept("**/constructs/v3.3.161/docs-typescript.md", async (req) => {
|
|
27
|
+
req.reply({
|
|
28
|
+
fixture: "docs-typescript-constructs@3.3.161.md",
|
|
29
|
+
});
|
|
30
|
+
}).as("getDocs", { type: "static" });
|
|
31
|
+
|
|
32
|
+
cy.intercept("**/constructs/v10.0.9/assembly.json", async (req) => {
|
|
33
|
+
req.reply({
|
|
34
|
+
fixture: "assembly-constructs@10.0.9",
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
cy.intercept("**/constructs/v10.0.9/metadata.json", async (req) => {
|
|
39
|
+
req.reply({
|
|
40
|
+
fixture: "metadata-constructs@10.0.9",
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
cy.intercept("**/constructs/v10.0.9/docs-typescript.md", async (req) => {
|
|
45
|
+
req.reply({
|
|
46
|
+
fixture: "docs-typescript-constructs@10.0.9.md",
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
cy.intercept("**/catalog.json", async (req) => {
|
|
51
|
+
req.reply({
|
|
52
|
+
fixture: "catalog",
|
|
53
|
+
});
|
|
54
|
+
}).as("getCatalog", { type: "static" });
|
|
55
|
+
|
|
56
|
+
cy.intercept("**/all-versions.json", async (req) => {
|
|
57
|
+
req.reply({
|
|
58
|
+
fixture: "all-versions",
|
|
59
|
+
});
|
|
60
|
+
}).as("getVersions", { type: "static" });
|
|
61
|
+
|
|
62
|
+
cy.visit(
|
|
63
|
+
getPackagePath({
|
|
64
|
+
name: "constructs",
|
|
65
|
+
version: "3.3.161",
|
|
66
|
+
language: "typescript" as any,
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
cy.wait("@getDocs");
|
|
71
|
+
cy.wait("@getCatalog");
|
|
72
|
+
cy.wait("@getVersions");
|
|
73
|
+
|
|
74
|
+
cy.getByDataTest(header.container).should("be.visible");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("Has feedback and report links", () => {
|
|
78
|
+
cy.getByDataTest(packagePage.feedbackLinks)
|
|
79
|
+
.should("be.visible")
|
|
80
|
+
.within(() => {
|
|
81
|
+
cy.getByDataTest(packagePage.reportAbuseLink)
|
|
82
|
+
.should("be.visible")
|
|
83
|
+
.should(
|
|
84
|
+
"have.attr",
|
|
85
|
+
"href",
|
|
86
|
+
`mailto:abuse@amazonaws.com?subject=${encodeURIComponent(
|
|
87
|
+
`ConstructHub - Report of abusive package: constructs`
|
|
88
|
+
)}`
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
cy.getByDataTest(packagePage.reportLink)
|
|
92
|
+
.should("be.visible")
|
|
93
|
+
.should(
|
|
94
|
+
"have.attr",
|
|
95
|
+
"href",
|
|
96
|
+
`${CONSTRUCT_HUB_REPO_URL}/issues/new`
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
cy.getByDataTest(packagePage.githubLink)
|
|
100
|
+
.should("be.visible")
|
|
101
|
+
.should(
|
|
102
|
+
"have.attr",
|
|
103
|
+
"href",
|
|
104
|
+
`https://github.com/aws/constructs/issues`
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("Can switch between versions of a package", () => {
|
|
110
|
+
const versions = [...versionsFixture.packages.constructs];
|
|
111
|
+
versions.sort(semver.rcompare);
|
|
112
|
+
|
|
113
|
+
cy.getByDataTest(markdown.container)
|
|
114
|
+
.should("contain", "Fake README description for v3.3.161");
|
|
115
|
+
|
|
116
|
+
cy.getByDataTest(packagePage.selectVersionDropdown)
|
|
117
|
+
.children('option')
|
|
118
|
+
.then(options => {
|
|
119
|
+
const actual = [...options as any].map(o => o.value);
|
|
120
|
+
const expected = versions;
|
|
121
|
+
expect(actual).to.deep.eq(expected);
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
cy.getByDataTest(packagePage.selectVersionDropdown)
|
|
125
|
+
.select("v10.0.9");
|
|
126
|
+
|
|
127
|
+
cy.url().should(
|
|
128
|
+
"contain",
|
|
129
|
+
getPackagePath({
|
|
130
|
+
name: "constructs",
|
|
131
|
+
version: "10.0.9",
|
|
132
|
+
language: Language.TypeScript,
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
// validate that new metadata has loaded
|
|
137
|
+
cy.getByDataTest(packagePage.description)
|
|
138
|
+
.should("contain", "A programming model for software-defined state");
|
|
139
|
+
|
|
140
|
+
// validate that new docs have loaded
|
|
141
|
+
cy.getByDataTest(markdown.container)
|
|
142
|
+
.should("contain", "Fake README description for v10.0.9");
|
|
143
|
+
|
|
144
|
+
cy.getByDataTest(packagePage.selectVersionDropdown)
|
|
145
|
+
.should("be.visible")
|
|
146
|
+
.should("contain", "v10.0.9");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("has a dependencies tab with dependency links", () => {
|
|
150
|
+
const depEntries = Object.entries(assemblyFixture.dependencies);
|
|
151
|
+
|
|
152
|
+
cy.getByDataTest(packagePage.dependenciesTab).should("be.visible").click();
|
|
153
|
+
|
|
154
|
+
cy.getByDataTest(packagePage.dependenciesList)
|
|
155
|
+
.should("be.visible")
|
|
156
|
+
.within(() => {
|
|
157
|
+
cy.getByDataTest(packagePage.dependenciesLink)
|
|
158
|
+
.should("have.length", depEntries.length)
|
|
159
|
+
.each((el, i) => {
|
|
160
|
+
const [name, version] = depEntries[i];
|
|
161
|
+
|
|
162
|
+
cy.wrap(el).should(
|
|
163
|
+
"have.attr",
|
|
164
|
+
"href",
|
|
165
|
+
getPackagePath({ name, version: sanitizeVersion(version) })
|
|
166
|
+
);
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import packageCardIds from "components/PackageCard/testIds";
|
|
2
|
+
import searchBar from "components/SearchBar/testIds";
|
|
3
|
+
import searchRedesign from "views/Search/testIds";
|
|
4
|
+
import { checkHeaderAndFooter } from "../support/helpers";
|
|
5
|
+
import { getSearchPath } from "util/url";
|
|
6
|
+
import { CatalogSearchSort } from "api/catalog-search/constants";
|
|
7
|
+
import { CDKType } from "constants/constructs";
|
|
8
|
+
import { SORT_RENDER_MAP } from "views/Search/constants";
|
|
9
|
+
import { Language, TEMP_SUPPORTED_LANGUAGES } from "constants/languages";
|
|
10
|
+
|
|
11
|
+
const checkCard = (cardType: string) => {
|
|
12
|
+
cy.getByDataTest(cardType).each(() => {
|
|
13
|
+
cy.getByDataTest(packageCardIds.title).should("be.visible");
|
|
14
|
+
cy.getByDataTest(packageCardIds.description).should("be.visible");
|
|
15
|
+
cy.getByDataTest(packageCardIds.published).should("be.visible");
|
|
16
|
+
cy.getByDataTest(packageCardIds.author).should("be.visible");
|
|
17
|
+
cy.getByDataTest([packageCardIds.downloads, packageCardIds.version]).should(
|
|
18
|
+
"be.visible"
|
|
19
|
+
);
|
|
20
|
+
cy.getByDataTest(packageCardIds.languages).should("be.visible");
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("Search", () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
cy.visit("/search");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
checkHeaderAndFooter();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("Search (Redesign / WIP)", () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
cy.visitWithConfig("/search", {
|
|
35
|
+
featureFlags: {
|
|
36
|
+
searchRedesign: true,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("Results Area", () => {
|
|
42
|
+
it("has expected elements for Wide Cards", () => {
|
|
43
|
+
checkCard(packageCardIds.wideContainer);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("can go to next page", () => {
|
|
47
|
+
cy.getByDataTest(searchRedesign.nextPage)
|
|
48
|
+
.click()
|
|
49
|
+
.url()
|
|
50
|
+
.should("contain", getSearchPath({ query: "", offset: 1 }));
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("can go to previous page", () => {
|
|
54
|
+
cy.visitWithConfig(getSearchPath({ offset: 3 }), {
|
|
55
|
+
featureFlags: { searchRedesign: true },
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
cy.getByDataTest(searchRedesign.prevPage)
|
|
59
|
+
.click()
|
|
60
|
+
.url()
|
|
61
|
+
.should("contain", getSearchPath({ query: "", offset: 2 }));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("can jump to a page", () => {
|
|
65
|
+
cy.visitWithConfig("/search", {
|
|
66
|
+
featureFlags: { searchRedesign: true },
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
cy.getByDataTest(searchRedesign.goToPage)
|
|
70
|
+
.clear()
|
|
71
|
+
.type("5{enter}")
|
|
72
|
+
.url()
|
|
73
|
+
.should("contain", getSearchPath({ query: "", offset: 4 }));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("Filters Panel", () => {
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
cy.visitWithConfig("/search", {
|
|
80
|
+
featureFlags: {
|
|
81
|
+
searchRedesign: true,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const filterByCDKType = (cdkType: CDKType) => {
|
|
87
|
+
cy.getByDataTest(searchRedesign.cdkTypeFilter)
|
|
88
|
+
.find(`[data-value="${cdkType}"]`)
|
|
89
|
+
.click();
|
|
90
|
+
|
|
91
|
+
cy.url().should("contain", getSearchPath({ query: "", cdkType }));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const filterByCDKMajors = (cdkType: CDKType, versions: number[]) => {
|
|
95
|
+
filterByCDKType(cdkType);
|
|
96
|
+
|
|
97
|
+
versions.forEach((cdkMajor) => {
|
|
98
|
+
cy.getByDataTest(searchRedesign.cdkVersionFilter)
|
|
99
|
+
.find(`[data-value="${cdkMajor}"]`)
|
|
100
|
+
.click()
|
|
101
|
+
.url()
|
|
102
|
+
.should("contain", getSearchPath({ query: "", cdkType, cdkMajor }));
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
it("has expected core filters", () => {
|
|
107
|
+
cy.getByDataTest(searchRedesign.filtersPanel)
|
|
108
|
+
.should("be.visible")
|
|
109
|
+
.each(() => {
|
|
110
|
+
[
|
|
111
|
+
searchRedesign.cdkTypeFilter,
|
|
112
|
+
searchRedesign.languagesFilter,
|
|
113
|
+
].forEach((testid) => {
|
|
114
|
+
cy.getByDataTest(testid).should("be.visible");
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// If this test fails, it may be an indication of data failure in catalog.json
|
|
120
|
+
it("can filter by CDK Type", () => {
|
|
121
|
+
cy.getByDataTest(searchRedesign.filtersPanel).each(() => {
|
|
122
|
+
[CDKType.awscdk, CDKType.cdk8s, CDKType.cdktf].forEach(filterByCDKType);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Only applies to CDKTypes with more than one version
|
|
127
|
+
it("can filter by CDK Version for each CDK Type", () => {
|
|
128
|
+
cy.getByDataTest(searchRedesign.filtersPanel).each(() => {
|
|
129
|
+
filterByCDKMajors(CDKType.awscdk, [0, 1, 2]);
|
|
130
|
+
filterByCDKMajors(CDKType.cdk8s, [0, 1]);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("can filter by languages", () => {
|
|
135
|
+
cy.getByDataTest(searchRedesign.languagesFilter).each(() => {
|
|
136
|
+
const languages = [];
|
|
137
|
+
|
|
138
|
+
cy.getByDataTest(searchRedesign.filterItem).each((el) => {
|
|
139
|
+
const lang = el.attr("data-value");
|
|
140
|
+
|
|
141
|
+
if (!TEMP_SUPPORTED_LANGUAGES.has(lang as Language)) return;
|
|
142
|
+
|
|
143
|
+
languages.push(lang);
|
|
144
|
+
|
|
145
|
+
cy.wrap(el)
|
|
146
|
+
.click()
|
|
147
|
+
.url()
|
|
148
|
+
.should("contain", getSearchPath({ query: "", languages }));
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Now deselect each language
|
|
152
|
+
cy.getByDataTest(searchRedesign.filterItem).each((el) => {
|
|
153
|
+
const lang = el.attr("data-value");
|
|
154
|
+
|
|
155
|
+
if (!TEMP_SUPPORTED_LANGUAGES.has(lang as Language)) return;
|
|
156
|
+
|
|
157
|
+
languages.shift();
|
|
158
|
+
|
|
159
|
+
cy.wrap(el)
|
|
160
|
+
.click()
|
|
161
|
+
.url()
|
|
162
|
+
.should("contain", getSearchPath({ query: "", languages }));
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe("Sorting", () => {
|
|
169
|
+
it("supports re-ordering of results", () => {
|
|
170
|
+
const sorts = [undefined, ...Object.values(CatalogSearchSort)];
|
|
171
|
+
|
|
172
|
+
sorts.forEach((sort) => {
|
|
173
|
+
cy.getByDataTest(searchRedesign.sortButton)
|
|
174
|
+
.click()
|
|
175
|
+
.getByDataTest(searchRedesign.sortDropdown)
|
|
176
|
+
.should("be.visible")
|
|
177
|
+
.each(() => {
|
|
178
|
+
// Not ideal, but for some reason .click() doesn't actually trigger the onClick for the buttons in cypress
|
|
179
|
+
if (sort === undefined) {
|
|
180
|
+
cy.getByDataTest(searchRedesign.sortItem).first().invoke("click");
|
|
181
|
+
} else {
|
|
182
|
+
cy.get(`[data-value="${sort}"]`).invoke("click");
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
cy.url().should(
|
|
187
|
+
"contain",
|
|
188
|
+
sort ? getSearchPath({ query: "", sort }) : "/search"
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
cy.getByDataTest(searchRedesign.sortButton).should(
|
|
192
|
+
"contain",
|
|
193
|
+
sort ? SORT_RENDER_MAP[sort] : "Relevance"
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe("Querying", () => {
|
|
200
|
+
it("supports searching by a query", () => {
|
|
201
|
+
cy.getByDataTest(searchRedesign.page).each(() => {
|
|
202
|
+
cy.getByDataTest(searchBar.input)
|
|
203
|
+
.type("@aws-cdk{enter}")
|
|
204
|
+
.url()
|
|
205
|
+
.should("include", `/search?q=${encodeURIComponent("@aws-cdk")}`);
|
|
206
|
+
|
|
207
|
+
cy.getByDataTest(searchRedesign.searchDetails).should(
|
|
208
|
+
"contain",
|
|
209
|
+
"@aws-cdk"
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests the potential xss vectors in the application
|
|
3
|
+
* @todo: Commented tests are for code that is not merged yet
|
|
4
|
+
*/
|
|
5
|
+
import header from "components/Header/testIds";
|
|
6
|
+
import markdown from "components/Markdown/testIds";
|
|
7
|
+
import searchBar from "components/SearchBar/testIds";
|
|
8
|
+
import { getPackagePath, getSearchPath } from "util/url";
|
|
9
|
+
|
|
10
|
+
const alertHTML = "<script>window.alert()</script>";
|
|
11
|
+
const alertJS = "window.alert()";
|
|
12
|
+
|
|
13
|
+
const withWindowAlertCheck = (assertion: () => Promise<unknown>) => {
|
|
14
|
+
cy.window().then((win) => {
|
|
15
|
+
cy.spy(win, "alert");
|
|
16
|
+
|
|
17
|
+
assertion().then(() => {
|
|
18
|
+
expect(win.alert).not.to.be.called;
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const checkURL = (params: Parameters<typeof getSearchPath>[0]) => {
|
|
24
|
+
cy.url().should("eq", `${Cypress.config().baseUrl}${getSearchPath(params)}`);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const testSearchURL = async (query: string) => {
|
|
28
|
+
withWindowAlertCheck(async () => {
|
|
29
|
+
cy.visit(decodeURIComponent(getSearchPath({ query })));
|
|
30
|
+
|
|
31
|
+
cy.getByDataTest(header.container).should("be.visible");
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const testInput = async ({ input = "", url = "/" }) => {
|
|
36
|
+
withWindowAlertCheck(async () => {
|
|
37
|
+
cy.visit(url);
|
|
38
|
+
|
|
39
|
+
cy.getByDataTest(searchBar.input).type(input + "{enter}", { force: true });
|
|
40
|
+
|
|
41
|
+
checkURL({ query: input });
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const testMarkdown = async () => {
|
|
46
|
+
withWindowAlertCheck(async () => {
|
|
47
|
+
cy.intercept("**/assembly.json", async (req) => {
|
|
48
|
+
req.reply({
|
|
49
|
+
fixture: "assembly",
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
cy.intercept("**/metadata.json", async (req) => {
|
|
54
|
+
req.reply({
|
|
55
|
+
fixture: "metadata",
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
cy.intercept("**/docs-typescript.md", async (req) => {
|
|
60
|
+
req.reply({
|
|
61
|
+
fixture: "xss-docs.md",
|
|
62
|
+
});
|
|
63
|
+
}).as("getDocs");
|
|
64
|
+
|
|
65
|
+
cy.visit(
|
|
66
|
+
getPackagePath({
|
|
67
|
+
name: "construct-hub",
|
|
68
|
+
version: "0.2.31",
|
|
69
|
+
language: "typescript" as any,
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
cy.wait("@getDocs");
|
|
74
|
+
|
|
75
|
+
cy.getByDataTest(header.container).should("be.visible");
|
|
76
|
+
// Give extra long timeout for CI
|
|
77
|
+
cy.getByDataTest(markdown.container, { timeout: 60000 }).should("exist");
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
describe("XSS - Stable Featureset", () => {
|
|
82
|
+
describe("Package Page - Markdown Rendering", () => {
|
|
83
|
+
it("will not execute malicious HTML or JS Markdown", () => {
|
|
84
|
+
testMarkdown();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("XSS - GA Featureset", () => {
|
|
90
|
+
describe("Home Page - Input", () => {
|
|
91
|
+
it("will not execute malicious HTML input", () => {
|
|
92
|
+
testInput({
|
|
93
|
+
input: alertHTML,
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("will not execute malicious JavaScript input", () => {
|
|
98
|
+
testInput({
|
|
99
|
+
input: alertJS,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe("Search Page - URL & Input", () => {
|
|
105
|
+
it("will not execute malicious HTML urls", () => {
|
|
106
|
+
testSearchURL(alertHTML);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("will not execute malicious JS urls", () => {
|
|
110
|
+
testSearchURL(alertJS);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("will not execute malicious HTML input", () => {
|
|
114
|
+
testInput({
|
|
115
|
+
url: "/search",
|
|
116
|
+
input: alertHTML,
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("will not execute malicious JS input", () => {
|
|
121
|
+
testInput({
|
|
122
|
+
url: "/search",
|
|
123
|
+
input: alertJS,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "./commands";
|
|
2
|
+
|
|
3
|
+
beforeEach(() => {
|
|
4
|
+
if (window.navigator && navigator.serviceWorker) {
|
|
5
|
+
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
|
6
|
+
registrations.forEach((registration) => {
|
|
7
|
+
registration.unregister();
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'cypress'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
blockedHosts: ['*.awsstatic.com', '*omtrdc.net', '*.shortbread.aws.dev'],
|
|
5
|
+
chromeWebSecurity: false,
|
|
6
|
+
defaultCommandTimeout: 15000,
|
|
7
|
+
retries: {
|
|
8
|
+
runMode: 2,
|
|
9
|
+
openMode: 1,
|
|
10
|
+
},
|
|
11
|
+
e2e: {
|
|
12
|
+
// We've imported your old cypress plugins here.
|
|
13
|
+
// You may want to clean this up later by importing these.
|
|
14
|
+
setupNodeEvents(on, config) {
|
|
15
|
+
return require('./cypress/plugins/index.js')(on, config)
|
|
16
|
+
},
|
|
17
|
+
baseUrl: 'http://localhost:3000',
|
|
18
|
+
},
|
|
19
|
+
})
|
package/package.json
CHANGED
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"@testing-library/user-event": "^13.5.0",
|
|
45
45
|
"@types/jest": "^26.0.24",
|
|
46
46
|
"@types/lunr": "^2.3.7",
|
|
47
|
-
"@types/node": "^
|
|
47
|
+
"@types/node": "^18",
|
|
48
48
|
"@types/node-emoji": "^1.8.2",
|
|
49
49
|
"@types/react": "17.0.80",
|
|
50
50
|
"@types/react-dom": "17.0.25",
|
|
51
51
|
"@types/react-helmet": "6.1.7",
|
|
52
52
|
"@types/react-router-dom": "5.3.3",
|
|
53
53
|
"@types/semver": "^7.5.8",
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
55
|
-
"@typescript-eslint/parser": "^
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^7",
|
|
55
|
+
"@typescript-eslint/parser": "^7",
|
|
56
56
|
"constructs": "^10.0.0",
|
|
57
|
-
"cypress": "
|
|
57
|
+
"cypress": "^13.11.0",
|
|
58
58
|
"eslint": "^8",
|
|
59
59
|
"eslint-config-prettier": "^8.10.0",
|
|
60
60
|
"eslint-import-resolver-typescript": "^2.7.1",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"express-http-proxy": "^1.6.3",
|
|
69
69
|
"jsii-docgen": "^6.3.27",
|
|
70
70
|
"prettier": "^2.8.8",
|
|
71
|
-
"projen": "^0.82.
|
|
71
|
+
"projen": "^0.82.6",
|
|
72
72
|
"react-app-rewired": "^2.2.1",
|
|
73
73
|
"react-scripts": "^5",
|
|
74
74
|
"standard-version": "^9",
|
|
@@ -84,12 +84,12 @@
|
|
|
84
84
|
"@chakra-ui/theme-tools": "^1.3.6",
|
|
85
85
|
"@emotion/react": "^11",
|
|
86
86
|
"@emotion/styled": "^11",
|
|
87
|
-
"@jsii/spec": "^1.
|
|
87
|
+
"@jsii/spec": "^1.100.0",
|
|
88
88
|
"copy-to-clipboard": "^3.3.3",
|
|
89
89
|
"date-fns": "^2.30.0",
|
|
90
90
|
"framer-motion": "^4",
|
|
91
91
|
"hast-util-sanitize": "^3.0.2",
|
|
92
|
-
"jsii-reflect": "^1.
|
|
92
|
+
"jsii-reflect": "^1.100.0",
|
|
93
93
|
"lunr": "^2.3.9",
|
|
94
94
|
"node-emoji": "^1.11.0",
|
|
95
95
|
"prism-react-renderer": "^1.3.5",
|
|
@@ -118,13 +118,13 @@
|
|
|
118
118
|
"wrap-ansi": "7.0.0"
|
|
119
119
|
},
|
|
120
120
|
"engines": {
|
|
121
|
-
"node": ">=
|
|
121
|
+
"node": ">= 18.20.0"
|
|
122
122
|
},
|
|
123
123
|
"license": "Apache-2.0",
|
|
124
124
|
"publishConfig": {
|
|
125
125
|
"access": "public"
|
|
126
126
|
},
|
|
127
|
-
"version": "0.1.
|
|
127
|
+
"version": "0.1.1121",
|
|
128
128
|
"eslintConfig": {
|
|
129
129
|
"extends": [
|
|
130
130
|
"react-app",
|
package/cypress.json
DELETED