From 1d453bdd49abe3028dce1449c8c0f8a0cddfed5e Mon Sep 17 00:00:00 2001 From: Graydogminer <78515166+Graydogminer@users.noreply.github.com> Date: Sun, 13 Nov 2022 14:45:42 -0800 Subject: [PATCH 01/22] Update phase1.md --- admin/cipipeline/phase1.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/admin/cipipeline/phase1.md b/admin/cipipeline/phase1.md index 046ee84..ccb48f0 100644 --- a/admin/cipipeline/phase1.md +++ b/admin/cipipeline/phase1.md @@ -31,6 +31,9 @@ So far the features listed below have been completed to some degree: - Linting (JS) - Implemented: ction triggers on any PR, uses eslint to perform style enforcement on all JS components - ToDo: trigger workflow only on certain PRs which relate to JS code +- Linting (HTML) + - Implemented: action triggers on any PR, uses HTMLhint to perform style enforcement on all HTML components +- Linting (CSS) + - Implemented: action triggers on any PR, uses Stylelint to perform style enforcement on all CSS components - -## Planned Features and Timeline \ No newline at end of file +## Planned Features and Timeline From cc6df228edd4ff06b2969e087c02921aa031ebb6 Mon Sep 17 00:00:00 2001 From: Graydogminer <78515166+Graydogminer@users.noreply.github.com> Date: Mon, 14 Nov 2022 00:48:27 -0800 Subject: [PATCH 02/22] Create 111422-htmllinting-htmlhint.md --- specs/adrs/111422-htmllinting-htmlhint.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 specs/adrs/111422-htmllinting-htmlhint.md diff --git a/specs/adrs/111422-htmllinting-htmlhint.md b/specs/adrs/111422-htmllinting-htmlhint.md new file mode 100644 index 0000000..0bd3471 --- /dev/null +++ b/specs/adrs/111422-htmllinting-htmlhint.md @@ -0,0 +1,19 @@ +# Use HTMLhint for HTML linting framework + +- Status: accept +- Deciders: Arthur Lu, Marc Reta +- Date: 11 / 14 / 22 + +## Decision Drivers + +- Need linting to work with multiple style standards +- Need linting to be fast and informative + +## Considered Options + +- HTMLhint +- HTML-validate + +## Decision Outcome + +Chosen Option: HTMLhint for its low configuration complexity. From 81ada40ca3c59969efeb1335cb0faade5fef8b14 Mon Sep 17 00:00:00 2001 From: Graydogminer <78515166+Graydogminer@users.noreply.github.com> Date: Mon, 14 Nov 2022 01:05:58 -0800 Subject: [PATCH 03/22] Create 111422-csslinting-stylelint.md --- specs/adrs/111422-csslinting-stylelint.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 specs/adrs/111422-csslinting-stylelint.md diff --git a/specs/adrs/111422-csslinting-stylelint.md b/specs/adrs/111422-csslinting-stylelint.md new file mode 100644 index 0000000..d35b025 --- /dev/null +++ b/specs/adrs/111422-csslinting-stylelint.md @@ -0,0 +1,19 @@ +# Use Stylelint for CSS linting framework + +- Status: accept +- Deciders: Arthur Lu, Marc Reta +- Date: 11 / 14 / 22 + +## Decision Drivers + +- Need linting to work with multiple style standards +- Need linting to be fast and informative + +## Considered Options + +- Stylelint +- Prettier + +## Decision Outcome + +Chosen Option: Stylelint for its easy installation and unopinionated. From 02f493e33b5d9825ac41884ec4c8cbc20f660da9 Mon Sep 17 00:00:00 2001 From: look-its-ashton Date: Thu, 17 Nov 2022 11:53:51 -0800 Subject: [PATCH 04/22] sprint 2 meeting one rough draft --- admin/meetings/111722-sprint2meeting1.md | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 admin/meetings/111722-sprint2meeting1.md diff --git a/admin/meetings/111722-sprint2meeting1.md b/admin/meetings/111722-sprint2meeting1.md new file mode 100644 index 0000000..3fca69a --- /dev/null +++ b/admin/meetings/111722-sprint2meeting1.md @@ -0,0 +1,36 @@ +# Meeting Minutes (11/07/2022) +## Team 29: Hackers1995 +## Meeting Topic: First Sprint +Meeting notes for the first sprint + +## Attendance +1. Rhea Bhutada +2. George Dubinin +3. Gavyn Ezell +4. Henry Feng +5. Kara Hoagland +6. Marc Reta +7. Sanjit Joseph +8. Daniel Hernandez +9. Arthur Lu +10. Isaac Otero + +## Meeting Details +- When: 11/17/2022 at 11:30PM +- Where: Design & Innovation Building + +## Agenda: +- ### Old/Unresolved Business + - N/A +- ### New Business + - Second sprint commences! + - Focus on design progress for the project showoff + - + - +- ### Next Meeting's Business + +## Decisions Made +- + +## End Time +- 11/17/2022 at 1:00PM \ No newline at end of file From e4755dd0745e696fa7fe74fe31e1b28189051751 Mon Sep 17 00:00:00 2001 From: look-its-ashton Date: Thu, 17 Nov 2022 13:24:59 -0800 Subject: [PATCH 05/22] sprint 2 meeting one rough draft --- admin/meetings/111722-sprint2meeting1.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/admin/meetings/111722-sprint2meeting1.md b/admin/meetings/111722-sprint2meeting1.md index 3fca69a..01b31d9 100644 --- a/admin/meetings/111722-sprint2meeting1.md +++ b/admin/meetings/111722-sprint2meeting1.md @@ -25,8 +25,19 @@ Meeting notes for the first sprint - ### New Business - Second sprint commences! - Focus on design progress for the project showoff - - - - + - Cuisine vs Tag identifiers for reviews (both?) + - localStorage will hold: + - list of active IDs which is updated for very create operation. An ID uniquely identifies a review + - value, "nextId" denoting the index of the next available slot for an Id + - entries for every single review (javascript object) + - a list for every tag that denotes which Ids belong to reviews containing this tag + + End2end tests will rely on specific html element names which include the following: + - "create-btn" (located on homepage and used to create a new review) + - "submit-btn" (located on form and used to post review) + - "update-btn" (located on a specific review page) + - "delete-btn" (located on a specific review page) + - "tag-add-btn" (located on the review create form) - ### Next Meeting's Business ## Decisions Made From ca89953d41f7d89e8b2170ac038f0c5992666477 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Fri, 18 Nov 2022 09:31:53 +0000 Subject: [PATCH 06/22] add link to app in README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 84748ab..4a2b1cf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ # cse110-fa22-group29 -[Team Page Link](https://github.com/cse110-fa22-group29/cse110-fa22-group29/blob/main/admin/team.md) \ No newline at end of file + +[Team Page Link](https://github.com/cse110-fa22-group29/cse110-fa22-group29/blob/main/admin/team.md) + +[Food Journal](https://cse110-fa22-group29.github.io/cse110-fa22-group29/) \ No newline at end of file From 23ae101f5604135d3eedfcf8c6cfa585b1552e5e Mon Sep 17 00:00:00 2001 From: Gavyn Ezell <72951570+gavyn-ezell@users.noreply.github.com> Date: Sat, 19 Nov 2022 11:19:57 -0800 Subject: [PATCH 07/22] testing images Co-authored-by: d7hernan --- source/CreatePage.html | 112 +++++++++++++---------- source/assets/images/icons/Grouppink.png | Bin 0 -> 3591 bytes source/assets/images/icons/Logo.png | Bin 0 -> 24624 bytes source/assets/images/icons/favicon.ico | Bin 0 -> 30493 bytes source/static/CreatePage.css | 106 ++++++--------------- 5 files changed, 94 insertions(+), 124 deletions(-) create mode 100644 source/assets/images/icons/Grouppink.png create mode 100644 source/assets/images/icons/Logo.png create mode 100644 source/assets/images/icons/favicon.ico diff --git a/source/CreatePage.html b/source/CreatePage.html index bc37e7a..6c9c9c4 100644 --- a/source/CreatePage.html +++ b/source/CreatePage.html @@ -14,64 +14,80 @@ - + - -
-
- Pic: - - -
-
+ +
+ logo +

Food Journal

+ +
+
+

New Entry

- Meal: - - -
+ +
+ Pic: + + +
+
-
- Rating: - - - - - -
+ Meal: + + +
-
- Other Info: - - +
+ Other Info: + +
- - + + + + +
+ + + \ No newline at end of file diff --git a/source/assets/images/icons/Grouppink.png b/source/assets/images/icons/Grouppink.png new file mode 100644 index 0000000000000000000000000000000000000000..00cae3c010bbf4c6a0c810adc01e44cfb5eaf3c5 GIT binary patch literal 3591 zcmai1`%hD67(VSNlnT;T1VlujTG>}2`+nbn z+hJy)dB4X zTlyeoLBW_2IsshPklRxV-6L^Gvl$}!*H@2(oLw9+AGDjlcpVDJ1wDLuh2nl_L9&X7 z_s{X;VzhAj`L`iv_D80SoYVvsa7$NCYHi$0n!nE4V|4bzoB;vu-g)bY8oDztYDb`z zFDDhZ&!j`|09S)Lwu;rBX%Ff#F-i??&Z1+tZY43J8^E>T0gxjDrbt;D)VTHXJ8|ey z?hR%kV*8t_^~Lxzm(h6`ugAXln|8Qb>4v#AkTY&Ht)VP>TZjM={ zEM~}tyQ=^qQy#ApCGt=yUo@~GvUnnfB&^Gt#Dz!j=U>u;T>6do!_`o;5s9vWQtxJ! zyYEw(muG5>{|;|+`I(vfz{JEvpF42nd6-ikh@JvdD%Ch0m5r=;o|Q2WIQRJaLsm|| zbVLG>gK-br{qI+gC9$5snp>ZrgzDtMWpa6TIB+qjqaZ`$4tq`8^$?62l|6~=tE>$+ z!yE;@ynF&lk3cq<4?G&>TrAT;o@{mA_QCAS9e}(WOh2bCU_;-2=H=QgL){VkaCDSo zb^DgtiVKSP62PmlM z-3%krxC+uVnUVojG03{i?wAf2T21z#y9yqAVKfAhv&_kXfwCoA%|q!hc8L!;Fu9mZ zxT#EefjVWpa|An0%!Qqk{Cu=iVybQ7sO0~29QMOtuNQ*7%R3d=zITHd?y8OLcINKt zr#>F1{St-@8l0IvXtzrJ79NA8U>#`TR0b0SkO_Es2%}vw) zeh}yi@Z@B*0x#JcD=lDuPmptZ_K(NJD z9xf4ktZAL|p_?DWImD**OvE3)@uEC}tX|I5aa1ijRx5WYcRU2%jXU>EF`I~YlphRp zYF1P=C@g>j3V3ttD9hhl5)bGu3=2E&A<&+9{){}B=EkiKe~P%={EyG`W)b8zUVKk1 zmXNFV27(7A(jiJaye5?&b3nDl;Z)86RIvW{;BZ;{YWG48oZJ<=yPUOH{H(y4XZ8du zDs=N36&lH|w*`65fniZhy^9wTbHU21FKbqGtYp(pwoyy@Rs&Sg%{Oed&=ad52ElPq zM=%p6J9JtP!Eo}n1M-aP#fT5^*Z|qPAZ*-iUGMI5r;1sc>{vhV9}Q%>fi$kJ0nEvb zLym#*STp;%9qji&tS@(`@*2wl@7z&$uB|UWLlAIeY|P(Q3`4afd%q?l>k%j>;}S2$ zzfL?2326WSy_FxS_iSLHW2O~Ted_BvQ>Vg8k zI{^`{VQzTb1gs3eeg~>SqnMYE(O_WRtVG&Xu3MW|N}!cl)!~E1i$TCvWG4aY*UT(W zLw+q&$~zqRn#Yi7=5qghg?VLZ)EVKG0W9C2{x#_)mVP`gf2KYlMK1m#$T_UgQ!n3TPC#)v8DJQO$&HCnh|S?K>Q2VmB`Bg literal 0 HcmV?d00001 diff --git a/source/assets/images/icons/Logo.png b/source/assets/images/icons/Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..206693c3409a9f3a704d6c0f4ecb2067649bfddb GIT binary patch literal 24624 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 W+y+@Bz4+b!R#j#7%v#9+*#8IYwT0;b literal 0 HcmV?d00001 diff --git a/source/assets/images/icons/favicon.ico b/source/assets/images/icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f042014576f8680bb2b707491859551a1d47541c GIT binary patch literal 30493 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 DVLZj) literal 0 HcmV?d00001 diff --git a/source/static/CreatePage.css b/source/static/CreatePage.css index c347a04..ec7bf77 100644 --- a/source/static/CreatePage.css +++ b/source/static/CreatePage.css @@ -1,83 +1,37 @@ /* CreatePage.css */ -* { - font-family: sans-serif; +body{ + background-color: #13323b; } -body { - height: 100%; - width: 100%; -} - -fieldset { - border: 2px solid rgb(214 214 214); - box-sizing: border-box; - display: block; - width: max-content; -} - -form button { - display: block; - margin-top: 5px; -} - -label[for="ingredients"] p { - margin: 0; -} - -label[for="numRatings"] { - margin: 10px 0 0; -} - -label[for^="rating"] { - padding-right: 10px; -} - -label:not([for^="rating"]) { - display: block; - margin-bottom: 5px; -} - -main { - column-gap: 10px; - display: flex; - flex-wrap: wrap; - height: auto; - max-width: 660px; - row-gap: 10px; - width: 100%; -} - -.tag-container { - display: flex; - flex-flow: row wrap; -} - -.tag { - background-color: grey; - border-radius: 7px; - color: white; - padding-right: 7px; - padding-left: 7px; - margin: 3px; -} - -.tag::before { - display: inline-block; - content: "x"; - height: 15px; - width: 15px; - margin-right: 4px; +h1 { text-align: center; - color: white; - cursor: pointer; +} +.Top-Bar{ + margin-top: -8cm; +} +.Top-Bar > img{ + position: relative; + top: 7.85cm; +} +.Top-Bar > h1{ + position: relative; + top: 2.2cm; + font-size: 3cm; + color: #EAA9BC + +} +.Top-Bar > form{ + position: relative; + left: 32cm; } -.tag:hover::before { - color: red; -} - -.danger { - background-color: rgb(254 171 171); - border-color: red; -} +.journal-form { + font-size: 120%; + width: 50%; + display: block; + margin: auto; + color: #ccb3bb; + border: 3px solid rgb(7, 0, 0); + background-color: #b52754; +} \ No newline at end of file From 20e9842aea186f3cecefe961af729ff0dc8ed7b8 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sat, 19 Nov 2022 12:00:59 -0800 Subject: [PATCH 08/22] fix expected values for ratings and src tests Signed-off-by: Arthur Lu --- source/ReviewDetails.html | 2 +- source/assets/scripts/main.e2e.test.js | 32 ++++++++++++-------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/source/ReviewDetails.html b/source/ReviewDetails.html index 8c457aa..552c2f3 100644 --- a/source/ReviewDetails.html +++ b/source/ReviewDetails.html @@ -72,7 +72,7 @@ - + diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index 482f67c..48ec53c 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -43,7 +43,7 @@ describe("test App end to end", async () => { await page.waitForNavigation(); // Set text fields - await page.$eval("#mealImg", el => el.value = "sample src"); + await page.$eval("#mealImg", el => el.value = ""); await page.$eval("#imgAlt", el => el.value = "sample alt"); await page.$eval("#mealName", el => el.value = "sample name"); await page.$eval("#comments", el => el.value = "sample comment"); @@ -72,7 +72,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "sample src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); // Get the title, comment, and restaurant @@ -98,7 +98,7 @@ describe("test App end to end", async () => { // Check stars let stars = await page.$("#d-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/5-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); }); it("check home page", async () => { @@ -116,7 +116,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "sample src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); // Get the title, comment, and restaurant @@ -141,7 +141,7 @@ describe("test App end to end", async () => { // Check stars let stars = await shadowRoot.$("#a-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/5-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); }); }); @@ -154,7 +154,6 @@ describe("test App end to end", async () => { it("check details page", async () => { // click review card let review_card = await page.$("review-card"); - console.log(JSON.stringify(review_card)); await review_card.click(); await page.waitForNavigation(); @@ -163,7 +162,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "sample src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); // Get the title, comment, and restaurant @@ -189,7 +188,7 @@ describe("test App end to end", async () => { // Check stars let stars = await page.$("#d-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/5-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); }); it("check home page", async () => { @@ -207,7 +206,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "sample src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); // Get the title, comment, and restaurant @@ -232,7 +231,7 @@ describe("test App end to end", async () => { // Check stars let stars = await shadowRoot.$("#a-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/5-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); }); }); @@ -242,7 +241,6 @@ describe("test App end to end", async () => { // Get the only review card and click it let review_card = await page.$("review-card"); - console.log(JSON.stringify(review_card)); await review_card.click(); await page.waitForNavigation(); @@ -251,7 +249,7 @@ describe("test App end to end", async () => { await update_btn.click(); // Set text fields - await page.$eval("#mealImg", el => el.value = "updated src"); + await page.$eval("#mealImg", el => el.value = ""); await page.$eval("#imgAlt", el => el.value = "updated alt"); await page.$eval("#mealName", el => el.value = "updated name"); await page.$eval("#comments", el => el.value = "updated comment"); @@ -272,7 +270,7 @@ describe("test App end to end", async () => { // Select a new rating of 5 stars let rating_select = await page.$("#s5-select"); - await rating_selects.click(); + await rating_select.click(); // Click the save button to save updates let save_btn = await page.$("#save-btn"); @@ -286,7 +284,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "updated src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); // Get the title, comment, and restaurant @@ -311,7 +309,7 @@ describe("test App end to end", async () => { // Check stars let stars = await page.$("#d-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/1-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/5-star.svg"); }); it("check home page", async () => { @@ -329,7 +327,7 @@ describe("test App end to end", async () => { let imgSrc = await img.getProperty("src"); let imgAlt = await img.getProperty("alt"); // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "updated src"); + assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); // Get the title, comment, and restaurant @@ -354,7 +352,7 @@ describe("test App end to end", async () => { // Check stars let stars = await shadowRoot.$("#a-rating"); let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "./assets/images/icons/1-star.svg"); + assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/5-star.svg"); }); }); From 8338156cb8e32102663ef81c40c7dfdaadfcadef Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sat, 19 Nov 2022 12:16:03 -0800 Subject: [PATCH 09/22] fix delete test issue with alert handling Signed-off-by: Arthur Lu --- source/assets/scripts/main.e2e.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index 48ec53c..e9c93b8 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -364,6 +364,11 @@ describe("test App end to end", async () => { await review_card.click(); await page.waitForNavigation(); + page.on('dialog', async dialog => { + console.log(dialog.message()); + await dialog.accept(); + }); + // Get the delete button and click it let delete_btn = await page.$("#delete-btn"); await delete_btn.click(); From 5668e68594a6e9c62e37f5deb60b448ba42bc0f1 Mon Sep 17 00:00:00 2001 From: Gavyn Ezell <72951570+gavyn-ezell@users.noreply.github.com> Date: Sat, 19 Nov 2022 12:29:50 -0800 Subject: [PATCH 10/22] first style integration Co-authored-by: d7hernan Co-authored-by: look-its-ashton --- source/CreatePage.html | 3 +- source/assets/images/icons/Grouppink.png | Bin 3591 -> 2050 bytes source/assets/images/icons/Logo.png | Bin 24624 -> 13603 bytes source/assets/images/icons/favicon.ico | Bin 30493 -> 16908 bytes source/assets/scripts/main.js | 4 +- source/index.html | 29 +++++++++- source/static/CreatePage.css | 47 ++++++++++++++++ source/static/homepage.css | 65 +++++++++++++++++++++++ 8 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 source/static/homepage.css diff --git a/source/CreatePage.html b/source/CreatePage.html index 6c9c9c4..222258a 100644 --- a/source/CreatePage.html +++ b/source/CreatePage.html @@ -15,12 +15,13 @@ + - +
logo

Food Journal

diff --git a/source/assets/images/icons/Grouppink.png b/source/assets/images/icons/Grouppink.png index 00cae3c010bbf4c6a0c810adc01e44cfb5eaf3c5..d4f1d141ee904bc00d0a060bfa34ab07c8217813 100644 GIT binary patch literal 2050 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 diff --git a/source/assets/images/icons/Logo.png b/source/assets/images/icons/Logo.png index 206693c3409a9f3a704d6c0f4ecb2067649bfddb..0f5cf7715537f195e7c7f96130ceb7456bb81957 100644 GIT binary patch literal 13603 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 W+y+@Bz4+b!R#j#7%v#9+*#8IYwT0;b diff --git a/source/assets/images/icons/favicon.ico b/source/assets/images/icons/favicon.ico index f042014576f8680bb2b707491859551a1d47541c..e0dd9ea7f0c8b089d53c91a1382e72b52345d301 100644 GIT binary patch literal 16908 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 XqC@F~v3`4g00000NkvXXu0mjf&7xRi literal 30493 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 DVLZj) diff --git a/source/assets/scripts/main.js b/source/assets/scripts/main.js index c402faf..38e182d 100644 --- a/source/assets/scripts/main.js +++ b/source/assets/scripts/main.js @@ -18,12 +18,12 @@ function init() { * @param {Array} reviews An array of reviews */ function addReviewsToDocument(reviews) { - let mainEl = document.querySelector("main"); + let box = document.getElementById("review-container"); reviews.forEach(review => { let newReview = document.createElement("review-card"); newReview.data = review; //TODO: want to append it to whatever the box is in layout - mainEl.append(newReview); + box.append(newReview); }); } diff --git a/source/index.html b/source/index.html index b8d4438..c72fe26 100644 --- a/source/index.html +++ b/source/index.html @@ -14,14 +14,39 @@ - + +
+ logo +

Food Journal

+
+ + +
+
+
+

Recent Reviews

+ CREATE + +
+
+
+
- + diff --git a/source/static/CreatePage.css b/source/static/CreatePage.css index ec7bf77..8d3a43e 100644 --- a/source/static/CreatePage.css +++ b/source/static/CreatePage.css @@ -34,4 +34,51 @@ h1 { color: #ccb3bb; border: 3px solid rgb(7, 0, 0); background-color: #b52754; +} + +.hidden, +.rating:not(:checked) > input { /* Hide radio circles while star rating */ + display: none; +} + +/* Unchecked stars */ +.rating:not(:checked) > label { + /* Make stars line up sideways and not vertically */ + float: right; + + /* Hide label text */ + width: 1em; + overflow: hidden; + white-space: nowrap; + + /* Star default color and size */ + font-size: 200%; + line-height: 1.2; + color: #b3b3cc; +} + +.rating > label:active { + position: relative; +} + +.rating:not(:checked) > label::before { + content: "★"; +} + +/* Checked star color */ +.rating > input:checked ~ label { + color: #ffbf00; +} + +.rating:not(:checked) > label:hover, +.rating:not(:checked) > label:hover ~ label { + color: orangered; +} + +.rating > input:checked + label:hover, +.rating > input:checked ~ label:hover, +.rating > input:checked + label:hover ~ label, +.rating > input:checked ~ label:hover ~ label, +.rating > label:hover ~ input:checked ~ label { + color: orangered; } \ No newline at end of file diff --git a/source/static/homepage.css b/source/static/homepage.css new file mode 100644 index 0000000..1aae749 --- /dev/null +++ b/source/static/homepage.css @@ -0,0 +1,65 @@ +/* homepage.css */ +/* Color*/ +body{ + background-color: #13323b; +} +.Top-Bar{ + margin-top: -8cm; +} +.Top-Bar > img{ + position: relative; + top: 7.5cm; +} +.Top-Bar > h1{ + position: relative; + left: 10.5cm; + top: 2.2cm; + font-size: 3cm; + color: #EAA9BC; + +} +.Top-Bar > form{ + position: relative; + left: 32cm; +} +.Review-boxes { + position: relative; +} + +.Review-boxes > h2 { + position: relative; + left: 10cm; + font-size: 1.5cm; + color: #EAA9BC; +} +.Review-boxes > input { + position: relative; + left: 20.34cm; + top: -3.5cm; +} + +.Filter-box{ + width:300px; + height:700px; + background: #8D4E62; + position: relative; + left: 29.5cm; + top: -5.5cm; +} +.review-container{ + display: flex; + position: relative; + top: -22cm; + left: 5cm; + max-width: 900px; + flex-wrap: wrap; +} +.review-container > div { + background-color: #f1f1f1; + width: 200px; + height: 200px; + margin: 10px; + text-align: center; + line-height: 75px; + font-size: 30px; + } \ No newline at end of file From 1c1ac64c58a8bf19e1086aa8c1f73371c203fd8c Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sat, 19 Nov 2022 12:34:29 -0800 Subject: [PATCH 11/22] change e2e tests to use default images Signed-off-by: Arthur Lu --- source/assets/scripts/main.e2e.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index e9c93b8..d9c7c20 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -43,7 +43,6 @@ describe("test App end to end", async () => { await page.waitForNavigation(); // Set text fields - await page.$eval("#mealImg", el => el.value = ""); await page.$eval("#imgAlt", el => el.value = "sample alt"); await page.$eval("#mealName", el => el.value = "sample name"); await page.$eval("#comments", el => el.value = "sample comment"); @@ -249,7 +248,6 @@ describe("test App end to end", async () => { await update_btn.click(); // Set text fields - await page.$eval("#mealImg", el => el.value = ""); await page.$eval("#imgAlt", el => el.value = "updated alt"); await page.$eval("#mealName", el => el.value = "updated name"); await page.$eval("#comments", el => el.value = "updated comment"); From bec66f13851651316b569cef44bf2fe2c446f147 Mon Sep 17 00:00:00 2001 From: look-its-ashton Date: Sun, 20 Nov 2022 13:18:00 -0800 Subject: [PATCH 12/22] Sprint 2 Meeting 3 Meeting Notes --- admin/meetings/112022-sprint2meeting3.md | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 admin/meetings/112022-sprint2meeting3.md diff --git a/admin/meetings/112022-sprint2meeting3.md b/admin/meetings/112022-sprint2meeting3.md new file mode 100644 index 0000000..c5f5a1b --- /dev/null +++ b/admin/meetings/112022-sprint2meeting3.md @@ -0,0 +1,33 @@ +# Meeting Minutes (11/20/2022) +## Team 29: Hackers1995 +## Meeting Topic: Second Sprint Meeting 3 + + +## Attendance +1. Rhea Bhutada +2. George Dubinin +3. Gavyn Ezell +4. Henry Feng +5. Kara Hoagland +6. Marc Reta +7. Sanjit Joseph +8. Daniel Hernandez +9. Arthur Lu +10. Isaac Otero + +## Meeting Details +- When: 11/20/2022 at 1:00PM +- Where: CSE Building Second Floor + +## Agenda: +- ### Old/Unresolved Business + - N/A +- ### New Business + - +- ### Next Meeting's Business + +## Decisions Made +- + +## End Time +- 11/20/2022 at 3:00PM \ No newline at end of file From 85d583e1b8fff83503c32b29ab5163c2cd25f8f8 Mon Sep 17 00:00:00 2001 From: look-its-ashton Date: Sun, 20 Nov 2022 13:37:25 -0800 Subject: [PATCH 13/22] updating sprint2meeting3 --- admin/meetings/112022-sprint2meeting3.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/admin/meetings/112022-sprint2meeting3.md b/admin/meetings/112022-sprint2meeting3.md index c5f5a1b..fdbaca0 100644 --- a/admin/meetings/112022-sprint2meeting3.md +++ b/admin/meetings/112022-sprint2meeting3.md @@ -23,7 +23,10 @@ - ### Old/Unresolved Business - N/A - ### New Business - - + - Planning for the Agile Steam Status Video + - *Present the status of your software* + - *Description of current challenges to development* + - *Preview of the next sprint and what to look forward to* - ### Next Meeting's Business ## Decisions Made From e7d8eaea59cbe5400581e79be38511406a421224 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 13:39:21 -0800 Subject: [PATCH 14/22] fix issue with tag checking, modularize frequent app opperations in appTestHelpers.js, fix isue with tage count checking Signed-off-by: Arthur Lu --- source/assets/scripts/appTestHelpers.js | 65 +++ source/assets/scripts/main.e2e.test.js | 535 +++++++++--------------- 2 files changed, 265 insertions(+), 335 deletions(-) create mode 100644 source/assets/scripts/appTestHelpers.js diff --git a/source/assets/scripts/appTestHelpers.js b/source/assets/scripts/appTestHelpers.js new file mode 100644 index 0000000..434d09f --- /dev/null +++ b/source/assets/scripts/appTestHelpers.js @@ -0,0 +1,65 @@ +import {strict as assert} from "node:assert"; + +export async function setReviewForm(page, review) { + + // Set text fields + await page.$eval("#imgAlt", (el, value) => el.value = value, review.imgAlt); + await page.$eval("#mealName", (el, value) => el.value = value, review.mealName); + await page.$eval("#comments", (el, value) => el.value = value, review.comments); + await page.$eval("#restaurant", (el, value) => el.value = value, review.restaurant); + + // Get all tag elements and click them to delete them + let tag_items = await page.$$(".tag"); + if(tag_items !== null){ + for(let i = 0; i < tag_items.length; i++){ + await tag_items[i].click(); + } + } + + // Get the button needed to add new tags + let tag_btn = await page.$("#tag-add-btn"); + for(let i = 0; i < review.tags.length; i++){ + await page.$eval("#tag-form", (el, value) => el.value = value, review.tags[i]); + await tag_btn.click(); + } + + // Select a new rating + let rating_select = await page.$(`#s${review.rating}-select`); + await rating_select.click({delay: 100}); +} + +export async function checkCorrectness(root, prefix, expected){ + // Get the review image and check src and alt + let img = await root.$(`#${prefix}-mealImg`); + let imgSrc = await img.getProperty("src"); + let imgAlt = await img.getProperty("alt"); + // Check src and alt + assert.strictEqual(await imgSrc.jsonValue(), expected.imgSrc); + assert.strictEqual(await imgAlt.jsonValue(), expected.imgAlt); + + // Get the title, comment, and restaurant + let title = await root.$(`#${prefix}-mealName`); + let title_text = await title.getProperty("innerText"); + let comment = await root.$(`#${prefix}-comments`); + let comment_text = await comment.getProperty("innerText"); + let restaurant = await root.$(`#${prefix}-restaurant`); + let restaurant_text = await restaurant.getProperty("innerText"); + + // Check title, comment, and restaurant + assert.strictEqual(await title_text.jsonValue(), expected.mealName); + assert.strictEqual(await comment_text.jsonValue(), expected.comments); + assert.strictEqual(await restaurant_text.jsonValue(), expected.restaurant); + + // Check tags + let tags = await root.$$(".tag"); + assert.strictEqual(await tags.length, expected.tags.length); + for(let i = 0; i < expected.tags.length; i++){ + let tag_text = await tags[i].getProperty("innerText"); + assert.strictEqual(await tag_text.jsonValue(), expected.tags[i]); + } + + // Check stars + let stars = await root.$(`#${prefix}-rating`); + let stars_src = await stars.getProperty("src"); + assert.strictEqual(await stars_src.jsonValue(), expected.rating); +} \ No newline at end of file diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index d9c7c20..278ac22 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -1,7 +1,8 @@ import {strict as assert} from "node:assert"; import {describe, it, before, after} from "mocha"; import puppeteer from "puppeteer-core"; -import { exit } from "node:process"; +import {exit} from "node:process"; +import {setReviewForm, checkCorrectness} from "./appTestHelpers.js" describe("test App end to end", async () => { @@ -17,6 +18,7 @@ describe("test App end to end", async () => { root = false; } + //browser = await puppeteer.launch({headless: false, slowMo: 250, args: root ? ['--no-sandbox'] : undefined}); browser = await puppeteer.launch({args: root ? ['--no-sandbox'] : undefined}); page = await browser.newPage(); try{ @@ -35,347 +37,210 @@ describe("test App end to end", async () => { }); }); - describe("test create 1 new review", async () => { - it("create 1 new review", async () => { - // Click the button to show update form - let create_btn = await page.$("#create-btn"); - await create_btn.click(); - await page.waitForNavigation(); + describe("test CRUD on simple inputs and default image", () => { - // Set text fields - await page.$eval("#imgAlt", el => el.value = "sample alt"); - await page.$eval("#mealName", el => el.value = "sample name"); - await page.$eval("#comments", el => el.value = "sample comment"); - await page.$eval("#restaurant", el => el.value = "sample restaurant"); + describe("test create 1 new review", async () => { + it("create 1 new review", async () => { + // Click the button to create a new review + let create_btn = await page.$("#create-btn"); + await create_btn.click(); + await page.waitForNavigation(); - // Get the button needed to add new tags - let tag_btn = await page.$("#tag-add-btn"); - for(let i = 0; i < 5; i++){ - await page.$eval("#tag-form", (el, value) => el.value = `tag ${value}`, i); - await tag_btn.click(); - } + // create a new review + let review = { + imgAlt: "sample alt", + mealName: "sample name", + comments: "sample comment", + restaurant: "sample restaurant", + tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], + rating: 1 + } + await setReviewForm(page, review); - // Select a new rating of 1 star - let rating_select = await page.$("#s1-select"); - await rating_select.click({delay: 100}); - - // Click the save button to save updates - let save_btn = await page.$("#save-btn"); - await save_btn.click(); - await page.waitForNavigation(); - }); - - it("check details page", async () => { - // Get the review image and check src and alt - let img = await page.$("#d-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); - - // Get the title, comment, and restaurant - let title = await page.$("#d-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await page.$("#d-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await page.$("#d-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "sample name"); - assert.strictEqual(await comment_text.jsonValue(), "sample comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "sample restaurant"); - - // Check tags - let tags = page.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `tag -${i}`); - } - - // Check stars - let stars = await page.$("#d-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); - }); - - it("check home page", async () => { - // Click the button to return to the home page - let home_btn = await page.$("#home-btn"); - home_btn.click(); - await page.waitForNavigation(); - - // Get the review card again and get its shadowRoot - let review_card = await page.$("review-card"); - let shadowRoot = await review_card.getProperty("shadowRoot"); - - // Get the review image and check src and alt - let img = await shadowRoot.$("#a-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); - - // Get the title, comment, and restaurant - let title = await shadowRoot.$("#a-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await shadowRoot.$("#a-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await shadowRoot.$("#a-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "sample name"); - assert.strictEqual(await comment_text.jsonValue(), "sample comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "sample restaurant"); - - // Check tags - let tags = shadowRoot.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `tag -${i}`); - } - - // Check stars - let stars = await shadowRoot.$("#a-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); - }); - }); - - describe("test read 1 review after refresh", async () => { - it("refresh page", async () => { - // Reload the page - await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); - }); - - it("check details page", async () => { - // click review card - let review_card = await page.$("review-card"); - await review_card.click(); - await page.waitForNavigation(); - - // Get the review image and check src and alt - let img = await page.$("#d-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); - - // Get the title, comment, and restaurant - let title = await page.$("#d-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await page.$("#d-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await page.$("#d-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "sample name"); - assert.strictEqual(await comment_text.jsonValue(), "sample comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "sample restaurant"); - - // Check tags - let tags = page.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `tag -${i}`); - } - - // Check stars - let stars = await page.$("#d-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); - }); - - it("check home page", async () => { - // Click the button to return to the home page - let home_btn = await page.$("#home-btn"); - home_btn.click(); - await page.waitForNavigation(); - - // Get the review card again and get its shadowRoot - let review_card = await page.$("review-card"); - let shadowRoot = await review_card.getProperty("shadowRoot"); - - // Get the review image and check src and alt - let img = await shadowRoot.$("#a-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); - - // Get the title, comment, and restaurant - let title = await shadowRoot.$("#a-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await shadowRoot.$("#a-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await shadowRoot.$("#a-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "sample name"); - assert.strictEqual(await comment_text.jsonValue(), "sample comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "sample restaurant"); - - // Check tags - let tags = shadowRoot.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `tag -${i}`); - } - - // Check stars - let stars = await shadowRoot.$("#a-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/1-star.svg"); - }); - }); - - describe("test update 1 review", async () => { - - it("update 1 review", async () => { - - // Get the only review card and click it - let review_card = await page.$("review-card"); - await review_card.click(); - await page.waitForNavigation(); - - // Click the button to show update form - let update_btn = await page.$("#update-btn"); - await update_btn.click(); - - // Set text fields - await page.$eval("#imgAlt", el => el.value = "updated alt"); - await page.$eval("#mealName", el => el.value = "updated name"); - await page.$eval("#comments", el => el.value = "updated comment"); - await page.$eval("#restaurant", el => el.value = "updated restaurant"); - - // Get all tag elements and click them to delete them - let tag_items = await page.$$(".tag"); - for(let i = 0; i < tag_items.length; i++){ - await tag_items[i].click(); - } - - // Get the button needed to add new tags - let tag_btn = await page.$("#tag-add-btn"); - for(let i = 0; i < 5; i++){ - await page.$eval("#tag-form", (el, value) => el.value = `updated tag -${value}`, i); - await tag_btn.click(); - } - - // Select a new rating of 5 stars - let rating_select = await page.$("#s5-select"); - await rating_select.click(); - - // Click the save button to save updates - let save_btn = await page.$("#save-btn"); - await save_btn.click(); - await page.waitForNavigation(); - }); - - it("check details page", async () => { - // Get the review image and check src and alt - let img = await page.$("#d-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); - - // Get the title, comment, and restaurant - let title = await page.$("#d-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await page.$("#d-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await page.$("#d-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "updated name"); - assert.strictEqual(await comment_text.jsonValue(), "updated comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "updated restaurant"); - - // Check tags - let tags = page.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `updated tag -${i}`); - } - - // Check stars - let stars = await page.$("#d-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/5-star.svg"); - }); - - it("check home page", async () => { - // Click the button to return to the home page - let home_btn = await page.$("#home-btn"); - home_btn.click(); - await page.waitForNavigation(); - - // Get the review card again and get its shadowRoot - let review_card = await page.$("review-card"); - let shadowRoot = await review_card.getProperty("shadowRoot"); - - // Get the review image and check src and alt - let img = await shadowRoot.$("#a-mealImg"); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), "http://localhost:8080/assets/images/icons/plate_with_cutlery.png"); - assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); - - // Get the title, comment, and restaurant - let title = await shadowRoot.$("#a-mealName"); - let title_text = await title.getProperty("innerText"); - let comment = await shadowRoot.$("#a-comments"); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await shadowRoot.$("#a-restaurant"); - let restaurant_text = await restaurant.getProperty("innerText"); - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), "updated name"); - assert.strictEqual(await comment_text.jsonValue(), "updated comment"); - assert.strictEqual(await restaurant_text.jsonValue(), "updated restaurant"); - - // Check tags - let tags = shadowRoot.$(".tag"); - for(let i = 0; i < tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), `tag -${i}`); - } - - // Check stars - let stars = await shadowRoot.$("#a-rating"); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), "http://localhost:8080/assets/images/icons/5-star.svg"); - }); - - }); - - describe("test delete 1 review", () => { - it("delete 1 review", async () => { - // Get the only review card and click it - let review_card = await page.$("review-card"); - await review_card.click(); - await page.waitForNavigation(); - - page.on('dialog', async dialog => { - console.log(dialog.message()); - await dialog.accept(); + // Click the save button to save updates + let save_btn = await page.$("#save-btn"); + await save_btn.click(); + await page.waitForNavigation(); }); - // Get the delete button and click it - let delete_btn = await page.$("#delete-btn"); - await delete_btn.click(); - await page.waitForNavigation(); + it("check details page", async () => { + // check the details page for correctness + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "sample alt", + mealName: "sample name", + comments: "sample comment", + restaurant: "sample restaurant", + tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], + rating: "http://localhost:8080/assets/images/icons/1-star.svg" + } + await checkCorrectness(page, "d", expected); + }); + + it("check home page", async () => { + // Click the button to return to the home page + let home_btn = await page.$("#home-btn"); + home_btn.click(); + await page.waitForNavigation(); - // Check that the card was correctly removed (there should be no remaining cards) - review_card = await page.$("#review-card"); - assert.strictEqual(review_card, null); + // Get the review card again and get its shadowRoot + let review_card = await page.$("review-card"); + let shadowRoot = await review_card.getProperty("shadowRoot"); + + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "sample alt", + mealName: "sample name", + comments: "sample comment", + restaurant: "sample restaurant", + tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], + rating: "http://localhost:8080/assets/images/icons/1-star.svg" + } + await checkCorrectness(shadowRoot, "a", expected); + }); }); + + describe("test read 1 review after refresh", async () => { + it("refresh page", async () => { + // Reload the page + await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); + }); + + it("check details page", async () => { + // click review card + let review_card = await page.$("review-card"); + await review_card.click(); + await page.waitForNavigation(); + + // check the details page for correctness + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "sample alt", + mealName: "sample name", + comments: "sample comment", + restaurant: "sample restaurant", + tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], + rating: "http://localhost:8080/assets/images/icons/1-star.svg" + } + await checkCorrectness(page, "d", expected); + }); + + it("check home page", async () => { + // Click the button to return to the home page + let home_btn = await page.$("#home-btn"); + home_btn.click(); + await page.waitForNavigation(); + + // Get the review card again and get its shadowRoot + let review_card = await page.$("review-card"); + let shadowRoot = await review_card.getProperty("shadowRoot"); + + // check the details page for correctness + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "sample alt", + mealName: "sample name", + comments: "sample comment", + restaurant: "sample restaurant", + tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], + rating: "http://localhost:8080/assets/images/icons/1-star.svg" + } + await checkCorrectness(shadowRoot, "a", expected); + }); + }); + + describe("test update 1 review", async () => { + + it("update 1 review", async () => { + + // Get the only review card and click it + let review_card = await page.$("review-card"); + await review_card.click(); + await page.waitForNavigation(); + + // Click the button to show update form + let update_btn = await page.$("#update-btn"); + await update_btn.click(); + + // create a new review + let review = { + imgAlt: "updated alt", + mealName: "updated name", + comments: "updated comment", + restaurant: "updated restaurant", + tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], + rating: 5 + } + await setReviewForm(page, review); + + // Click the save button to save updates + let save_btn = await page.$("#save-btn"); + await save_btn.click(); + await page.waitForNavigation(); + }); + + it("check details page", async () => { + // check the details page for correctness + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "updated alt", + mealName: "updated name", + comments: "updated comment", + restaurant: "updated restaurant", + tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], + rating: "http://localhost:8080/assets/images/icons/5-star.svg" + } + await checkCorrectness(page, "d", expected); + }); + + it("check home page", async () => { + // Click the button to return to the home page + let home_btn = await page.$("#home-btn"); + home_btn.click(); + await page.waitForNavigation(); + + // Get the review card again and get its shadowRoot + let review_card = await page.$("review-card"); + let shadowRoot = await review_card.getProperty("shadowRoot"); + + // check the details page for correctness + let expected = { + imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png", + imgAlt: "updated alt", + mealName: "updated name", + comments: "updated comment", + restaurant: "updated restaurant", + tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], + rating: "http://localhost:8080/assets/images/icons/5-star.svg" + } + await checkCorrectness(shadowRoot, "a", expected); + }); + + }); + + describe("test delete 1 review", () => { + it("delete 1 review", async () => { + // Get the only review card and click it + let review_card = await page.$("review-card"); + await review_card.click(); + await page.waitForNavigation(); + + page.on('dialog', async dialog => { + console.log(dialog.message()); + await dialog.accept(); + }); + + // Get the delete button and click it + let delete_btn = await page.$("#delete-btn"); + await delete_btn.click(); + await page.waitForNavigation(); + + // Check that the card was correctly removed (there should be no remaining cards) + review_card = await page.$("#review-card"); + assert.strictEqual(review_card, null); + }); + }); + }); after(async () => { From 3b1b0cfd57643d3c1f2183c2411dd57221edb023 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 13:39:52 -0800 Subject: [PATCH 15/22] quick async fix Signed-off-by: Arthur Lu --- source/assets/scripts/main.e2e.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index 278ac22..ad177c9 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -218,7 +218,7 @@ describe("test App end to end", async () => { }); - describe("test delete 1 review", () => { + describe("test delete 1 review", async () => { it("delete 1 review", async () => { // Get the only review card and click it let review_card = await page.$("review-card"); From 72e2f0fa030baa5f5b5aee1285c2c4bfe006d4a2 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 13:43:42 -0800 Subject: [PATCH 16/22] comment appTestHelpers.js Signed-off-by: Arthur Lu --- source/assets/scripts/appTestHelpers.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/assets/scripts/appTestHelpers.js b/source/assets/scripts/appTestHelpers.js index 434d09f..82ade7a 100644 --- a/source/assets/scripts/appTestHelpers.js +++ b/source/assets/scripts/appTestHelpers.js @@ -1,5 +1,10 @@ import {strict as assert} from "node:assert"; +/** + * Fills out a create or update review form + * @param {Object} page the page object which contains the create or update form + * @param {Object} review review data to input into the form + */ export async function setReviewForm(page, review) { // Set text fields @@ -28,6 +33,12 @@ export async function setReviewForm(page, review) { await rating_select.click({delay: 100}); } +/** + * Tests a page or shadowDOM for correct element text, src, or alt values + * @param {Object} root page or shodowDOM to test + * @param {string} prefix prefix character for element IDs + * @param {Object} expected values for eahc element + */ export async function checkCorrectness(root, prefix, expected){ // Get the review image and check src and alt let img = await root.$(`#${prefix}-mealImg`); From e73a544ab249646b406343bf12cd6c0ecc617169 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 14:07:01 -0800 Subject: [PATCH 17/22] fix js linting Signed-off-by: Arthur Lu --- source/assets/scripts/appTestHelpers.js | 150 ++++++++++++------------ source/assets/scripts/main.e2e.test.js | 22 ++-- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/source/assets/scripts/appTestHelpers.js b/source/assets/scripts/appTestHelpers.js index 82ade7a..12fd3c3 100644 --- a/source/assets/scripts/appTestHelpers.js +++ b/source/assets/scripts/appTestHelpers.js @@ -1,76 +1,76 @@ -import {strict as assert} from "node:assert"; - -/** - * Fills out a create or update review form - * @param {Object} page the page object which contains the create or update form - * @param {Object} review review data to input into the form - */ -export async function setReviewForm(page, review) { - - // Set text fields - await page.$eval("#imgAlt", (el, value) => el.value = value, review.imgAlt); - await page.$eval("#mealName", (el, value) => el.value = value, review.mealName); - await page.$eval("#comments", (el, value) => el.value = value, review.comments); - await page.$eval("#restaurant", (el, value) => el.value = value, review.restaurant); - - // Get all tag elements and click them to delete them - let tag_items = await page.$$(".tag"); - if(tag_items !== null){ - for(let i = 0; i < tag_items.length; i++){ - await tag_items[i].click(); - } - } - - // Get the button needed to add new tags - let tag_btn = await page.$("#tag-add-btn"); - for(let i = 0; i < review.tags.length; i++){ - await page.$eval("#tag-form", (el, value) => el.value = value, review.tags[i]); - await tag_btn.click(); - } - - // Select a new rating - let rating_select = await page.$(`#s${review.rating}-select`); - await rating_select.click({delay: 100}); -} - -/** - * Tests a page or shadowDOM for correct element text, src, or alt values - * @param {Object} root page or shodowDOM to test - * @param {string} prefix prefix character for element IDs - * @param {Object} expected values for eahc element - */ -export async function checkCorrectness(root, prefix, expected){ - // Get the review image and check src and alt - let img = await root.$(`#${prefix}-mealImg`); - let imgSrc = await img.getProperty("src"); - let imgAlt = await img.getProperty("alt"); - // Check src and alt - assert.strictEqual(await imgSrc.jsonValue(), expected.imgSrc); - assert.strictEqual(await imgAlt.jsonValue(), expected.imgAlt); - - // Get the title, comment, and restaurant - let title = await root.$(`#${prefix}-mealName`); - let title_text = await title.getProperty("innerText"); - let comment = await root.$(`#${prefix}-comments`); - let comment_text = await comment.getProperty("innerText"); - let restaurant = await root.$(`#${prefix}-restaurant`); - let restaurant_text = await restaurant.getProperty("innerText"); - - // Check title, comment, and restaurant - assert.strictEqual(await title_text.jsonValue(), expected.mealName); - assert.strictEqual(await comment_text.jsonValue(), expected.comments); - assert.strictEqual(await restaurant_text.jsonValue(), expected.restaurant); - - // Check tags - let tags = await root.$$(".tag"); - assert.strictEqual(await tags.length, expected.tags.length); - for(let i = 0; i < expected.tags.length; i++){ - let tag_text = await tags[i].getProperty("innerText"); - assert.strictEqual(await tag_text.jsonValue(), expected.tags[i]); - } - - // Check stars - let stars = await root.$(`#${prefix}-rating`); - let stars_src = await stars.getProperty("src"); - assert.strictEqual(await stars_src.jsonValue(), expected.rating); +import {strict as assert} from "node:assert"; + +/** + * Fills out a create or update review form + * @param {Object} page the page object which contains the create or update form + * @param {Object} review review data to input into the form + */ +export async function setReviewForm(page, review) { + + // Set text fields + await page.$eval("#imgAlt", (el, value) => el.value = value, review.imgAlt); + await page.$eval("#mealName", (el, value) => el.value = value, review.mealName); + await page.$eval("#comments", (el, value) => el.value = value, review.comments); + await page.$eval("#restaurant", (el, value) => el.value = value, review.restaurant); + + // Get all tag elements and click them to delete them + let tag_items = await page.$$(".tag"); + if(tag_items !== null){ + for(let i = 0; i < tag_items.length; i++){ + await tag_items[i].click(); + } + } + + // Get the button needed to add new tags + let tag_btn = await page.$("#tag-add-btn"); + for(let i = 0; i < review.tags.length; i++){ + await page.$eval("#tag-form", (el, value) => el.value = value, review.tags[i]); + await tag_btn.click(); + } + + // Select a new rating + let rating_select = await page.$(`#s${review.rating}-select`); + await rating_select.click({delay: 100}); +} + +/** + * Tests a page or shadowDOM for correct element text, src, or alt values + * @param {Object} root page or shodowDOM to test + * @param {string} prefix prefix character for element IDs + * @param {Object} expected values for eahc element + */ +export async function checkCorrectness(root, prefix, expected){ + // Get the review image and check src and alt + let img = await root.$(`#${prefix}-mealImg`); + let imgSrc = await img.getProperty("src"); + let imgAlt = await img.getProperty("alt"); + // Check src and alt + assert.strictEqual(await imgSrc.jsonValue(), expected.imgSrc); + assert.strictEqual(await imgAlt.jsonValue(), expected.imgAlt); + + // Get the title, comment, and restaurant + let title = await root.$(`#${prefix}-mealName`); + let title_text = await title.getProperty("innerText"); + let comment = await root.$(`#${prefix}-comments`); + let comment_text = await comment.getProperty("innerText"); + let restaurant = await root.$(`#${prefix}-restaurant`); + let restaurant_text = await restaurant.getProperty("innerText"); + + // Check title, comment, and restaurant + assert.strictEqual(await title_text.jsonValue(), expected.mealName); + assert.strictEqual(await comment_text.jsonValue(), expected.comments); + assert.strictEqual(await restaurant_text.jsonValue(), expected.restaurant); + + // Check tags + let tags = await root.$$(".tag"); + assert.strictEqual(await tags.length, expected.tags.length); + for(let i = 0; i < expected.tags.length; i++){ + let tag_text = await tags[i].getProperty("innerText"); + assert.strictEqual(await tag_text.jsonValue(), expected.tags[i]); + } + + // Check stars + let stars = await root.$(`#${prefix}-rating`); + let stars_src = await stars.getProperty("src"); + assert.strictEqual(await stars_src.jsonValue(), expected.rating); } \ No newline at end of file diff --git a/source/assets/scripts/main.e2e.test.js b/source/assets/scripts/main.e2e.test.js index ad177c9..38b5f3c 100644 --- a/source/assets/scripts/main.e2e.test.js +++ b/source/assets/scripts/main.e2e.test.js @@ -2,7 +2,7 @@ import {strict as assert} from "node:assert"; import {describe, it, before, after} from "mocha"; import puppeteer from "puppeteer-core"; import {exit} from "node:process"; -import {setReviewForm, checkCorrectness} from "./appTestHelpers.js" +import {setReviewForm, checkCorrectness} from "./appTestHelpers.js"; describe("test App end to end", async () => { @@ -19,7 +19,7 @@ describe("test App end to end", async () => { } //browser = await puppeteer.launch({headless: false, slowMo: 250, args: root ? ['--no-sandbox'] : undefined}); - browser = await puppeteer.launch({args: root ? ['--no-sandbox'] : undefined}); + browser = await puppeteer.launch({args: root ? ["--no-sandbox"] : undefined}); page = await browser.newPage(); try{ await page.goto("http://localhost:8080", {timeout: 1000}); @@ -54,7 +54,7 @@ describe("test App end to end", async () => { restaurant: "sample restaurant", tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], rating: 1 - } + }; await setReviewForm(page, review); // Click the save button to save updates @@ -73,7 +73,7 @@ describe("test App end to end", async () => { restaurant: "sample restaurant", tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], rating: "http://localhost:8080/assets/images/icons/1-star.svg" - } + }; await checkCorrectness(page, "d", expected); }); @@ -95,7 +95,7 @@ describe("test App end to end", async () => { restaurant: "sample restaurant", tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], rating: "http://localhost:8080/assets/images/icons/1-star.svg" - } + }; await checkCorrectness(shadowRoot, "a", expected); }); }); @@ -121,7 +121,7 @@ describe("test App end to end", async () => { restaurant: "sample restaurant", tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], rating: "http://localhost:8080/assets/images/icons/1-star.svg" - } + }; await checkCorrectness(page, "d", expected); }); @@ -144,7 +144,7 @@ describe("test App end to end", async () => { restaurant: "sample restaurant", tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"], rating: "http://localhost:8080/assets/images/icons/1-star.svg" - } + }; await checkCorrectness(shadowRoot, "a", expected); }); }); @@ -170,7 +170,7 @@ describe("test App end to end", async () => { restaurant: "updated restaurant", tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], rating: 5 - } + }; await setReviewForm(page, review); // Click the save button to save updates @@ -189,7 +189,7 @@ describe("test App end to end", async () => { restaurant: "updated restaurant", tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], rating: "http://localhost:8080/assets/images/icons/5-star.svg" - } + }; await checkCorrectness(page, "d", expected); }); @@ -212,7 +212,7 @@ describe("test App end to end", async () => { restaurant: "updated restaurant", tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"], rating: "http://localhost:8080/assets/images/icons/5-star.svg" - } + }; await checkCorrectness(shadowRoot, "a", expected); }); @@ -225,7 +225,7 @@ describe("test App end to end", async () => { await review_card.click(); await page.waitForNavigation(); - page.on('dialog', async dialog => { + page.on("dialog", async dialog => { console.log(dialog.message()); await dialog.accept(); }); From c3944d476becdbba0a5bfe880c118ed407662a49 Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 14:12:26 -0800 Subject: [PATCH 18/22] fix lintHTML and lintCSS commands Signed-off-by: Arthur Lu --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5dfc756..6ea0de5 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'", "lint": "eslint **/*.js", "fix-style": "eslint --fix **/*.js", - "lintHTML": "htmlhint '**/*.html'", - "lintCSS": "stylelint '**/*.css'", + "lintHTML": "htmlhint **/*.html", + "lintCSS": "stylelint **/*.css", "http-server": "http-server source" }, "devDependencies": { From 4f2d88db9f65303db239eded4a7438963b5fd9f4 Mon Sep 17 00:00:00 2001 From: rheabhutada02 <83424582+rheabhutada02@users.noreply.github.com> Date: Sun, 20 Nov 2022 14:12:34 -0800 Subject: [PATCH 19/22] Co-authored-by: Gavyn Ezell Co-authored-by: Kara Hoagland --- source/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/index.html b/source/index.html index c72fe26..96cbe6f 100644 --- a/source/index.html +++ b/source/index.html @@ -40,7 +40,7 @@

Recent Reviews

- CREATE + CREATE
From d284f0ddf231a468edcb59009508ccdafb5bd82a Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 14:17:10 -0800 Subject: [PATCH 20/22] change some npm scripts Signed-off-by: Arthur Lu --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6ea0de5..be9a691 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,11 @@ "type": "module", "scripts": { "test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'", - "lint": "eslint **/*.js", - "fix-style": "eslint --fix **/*.js", - "lintHTML": "htmlhint **/*.html", - "lintCSS": "stylelint **/*.css", + "lint-js": "eslint **/*.js", + "fix-js": "eslint --fix **/*.js", + "lint-html": "htmlhint **/*.html", + "lint-css": "stylelint **/*.css", + "fix-css": "stylelint --fix **/*.css", "http-server": "http-server source" }, "devDependencies": { From 3a7ed2fb1671c6075b2227c44829de2624a595ca Mon Sep 17 00:00:00 2001 From: Marc Date: Sun, 20 Nov 2022 14:26:48 -0800 Subject: [PATCH 21/22] fix stylelint to allow tabs as indent --- .stylelintrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.stylelintrc.json b/.stylelintrc.json index 2f1eeda..76eba38 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,3 +1,4 @@ { - "extends": "stylelint-config-standard" + "extends": "stylelint-config-standard", + "ignore": ["inside-parens", "param", "value"] } \ No newline at end of file From c5cc7bf30984b0cf320d3ff5ea1caba6e9ba843b Mon Sep 17 00:00:00 2001 From: Arthur Lu Date: Sun, 20 Nov 2022 14:36:13 -0800 Subject: [PATCH 22/22] update github actions with new npm script naming Signed-off-by: Arthur Lu --- .github/workflows/css-linting.yml | 2 +- .github/workflows/html-linting.yml | 2 +- .github/workflows/js-linting.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/css-linting.yml b/.github/workflows/css-linting.yml index fae3b66..48b333a 100644 --- a/.github/workflows/css-linting.yml +++ b/.github/workflows/css-linting.yml @@ -20,4 +20,4 @@ jobs: - name: Install dependencies run: sudo npm install - name: Run tests - run: sudo npm run lintCSS \ No newline at end of file + run: sudo npm run lint-css \ No newline at end of file diff --git a/.github/workflows/html-linting.yml b/.github/workflows/html-linting.yml index ab68590..c24292b 100644 --- a/.github/workflows/html-linting.yml +++ b/.github/workflows/html-linting.yml @@ -20,4 +20,4 @@ jobs: - name: Install dependencies run: sudo npm install - name: Run tests - run: sudo npm run lintHTML + run: sudo npm run lint-html diff --git a/.github/workflows/js-linting.yml b/.github/workflows/js-linting.yml index f3aafaf..b642926 100644 --- a/.github/workflows/js-linting.yml +++ b/.github/workflows/js-linting.yml @@ -22,4 +22,4 @@ jobs: - name: Install dependencies run: sudo npm install - name: Run tests - run: sudo npm run lint \ No newline at end of file + run: sudo npm run lint-js \ No newline at end of file