Merge remote-tracking branch 'origin/sprint-2' into allow-for-user-uploaded-images

This commit is contained in:
Henry Feng 2022-11-20 14:40:17 -08:00
commit 131553ddeb
22 changed files with 623 additions and 446 deletions

View File

@ -20,4 +20,4 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: sudo npm install run: sudo npm install
- name: Run tests - name: Run tests
run: sudo npm run lintCSS run: sudo npm run lint-css

View File

@ -20,4 +20,4 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: sudo npm install run: sudo npm install
- name: Run tests - name: Run tests
run: sudo npm run lintHTML run: sudo npm run lint-html

View File

@ -22,4 +22,4 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: sudo npm install run: sudo npm install
- name: Run tests - name: Run tests
run: sudo npm run lint run: sudo npm run lint-js

View File

@ -1,3 +1,4 @@
{ {
"extends": "stylelint-config-standard" "extends": "stylelint-config-standard",
"ignore": ["inside-parens", "param", "value"]
} }

View File

@ -1,2 +1,5 @@
# cse110-fa22-group29 # cse110-fa22-group29
[Team Page Link](https://github.com/cse110-fa22-group29/cse110-fa22-group29/blob/main/admin/team.md) [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/)

View File

@ -31,6 +31,9 @@ So far the features listed below have been completed to some degree:
- Linting (JS) - Linting (JS)
- Implemented: ction triggers on any PR, uses eslint to perform style enforcement on all JS components - 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 - 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 ## Planned Features and Timeline

View File

@ -0,0 +1,47 @@
# 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
- 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
-
## End Time
- 11/17/2022 at 1:00PM

View File

@ -0,0 +1,36 @@
# Meeting Minutes (11/20/2022)
## Team 29: Hackers1995
## Meeting Topic: Second Sprint Meeting 3
<what are we working on today>
## 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
- 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
-
## End Time
- 11/20/2022 at 3:00PM

View File

@ -4,10 +4,11 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'", "test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'",
"lint": "eslint **/*.js", "lint-js": "eslint **/*.js",
"fix-style": "eslint --fix **/*.js", "fix-js": "eslint --fix **/*.js",
"lintHTML": "htmlhint '**/*.html'", "lint-html": "htmlhint **/*.html",
"lintCSS": "stylelint '**/*.css'", "lint-css": "stylelint **/*.css",
"fix-css": "stylelint --fix **/*.css",
"http-server": "http-server source" "http-server": "http-server source"
}, },
"devDependencies": { "devDependencies": {

View File

@ -14,13 +14,29 @@
<!-- Main Stylesheets & Scripts --> <!-- Main Stylesheets & Scripts -->
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config--> <!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
<!-- <link rel="stylesheet" href="/static/reset.css" /> --> <!-- <link rel="stylesheet" href="/static/reset.css" /> -->
<link rel="stylesheet" href="./static/ReviewCard.css" /> <link rel="stylesheet" href="./static/CreatePage.css" />
<link rel="icon" href="./assets/images/icons/favicon.ico">
<script src="./assets/scripts/CreatePage.js" type="module"></script> <script src="./assets/scripts/CreatePage.js" type="module"></script>
</head> </head>
<body> <body>
<input type="button" value="Home" id="home-btn" onclick="window.location.assign('./index.html')"> <input type="button" value="Home" id="home-btn" onclick="window.location.assign('./index.html')">
<div class ="Top-Bar">
<img src ="./assets/images/icons/Logo.png" alt="logo" />
<h1> Food Journal </h1>
<!--
<form id="form">
<input type='search' id="seaching" name="searchBar" placeholder="Search journal...">
<button class="click" type="search">
Search
</button>
</form>
--->
</div>
<div class="journal-form">
<h1>New Entry </h1>
<form id="new-food-entry"> <form id="new-food-entry">
<fieldset> <fieldset>
<legend>Pic:</legend> <legend>Pic:</legend>
@ -39,7 +55,6 @@
</label> </label>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend> Meal: </legend> <legend> Meal: </legend>
<label for="Meal: ">Meal: <label for="Meal: ">Meal:
<input type="text" id="mealName" name="mealName" required> <input type="text" id="mealName" name="mealName" required>
@ -49,7 +64,6 @@
<textarea name="comments" id="comments"></textarea> <textarea name="comments" id="comments"></textarea>
</label> </label>
</fieldset> </fieldset>
<fieldset class="rating"> <fieldset class="rating">
<legend> Rating: </legend> <legend> Rating: </legend>
<input type="radio" id="s5" name="rating" value="5"/> <label for="s5" id="s5-select"> 5 stars </label> <input type="radio" id="s5" name="rating" value="5"/> <label for="s5" id="s5-select"> 5 stars </label>
@ -69,14 +83,15 @@
Tags: Tags:
<input type="text" id="tag-form" name="tag-form"> <input type="text" id="tag-form" name="tag-form">
<div class='tag-container' id="tag-container-form"> <div class='tag-container' id="tag-container-form">
</div> </div>
<button type="button" id="tag-add-btn">Add Tag</button> <button type="button" id="tag-add-btn">Add Tag</button>
</label> </label>
</fieldset> </fieldset>
<button type="submit" id="save-btn" value="Submit">Save Review</button> <button type="submit" id="save-btn" value="Submit">Save Review</button>
</form> </form>
</div>
</body> </body>
</html> </html>

View File

@ -77,7 +77,7 @@
</label> </label>
</fieldset> </fieldset>
<button type="submit" value="Submit">Add Review</button> <button type="submit" id="save-btn" value="Submit">Add Review</button>
</form> </form>
</body> </body>
</html> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +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);
}

View File

@ -2,6 +2,7 @@ import {strict as assert} from "node:assert";
import {describe, it, before, after} from "mocha"; import {describe, it, before, after} from "mocha";
import puppeteer from "puppeteer-core"; 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 () => { describe("test App end to end", async () => {
@ -17,7 +18,8 @@ describe("test App end to end", async () => {
root = false; root = false;
} }
browser = await puppeteer.launch({args: root ? ['--no-sandbox'] : undefined}); //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(); page = await browser.newPage();
try{ try{
await page.goto("http://localhost:8080", {timeout: 1000}); await page.goto("http://localhost:8080", {timeout: 1000});
@ -35,30 +37,25 @@ describe("test App end to end", async () => {
}); });
}); });
describe("test CRUD on simple inputs and default image", () => {
describe("test create 1 new review", async () => { describe("test create 1 new review", async () => {
it("create 1 new review", async () => { it("create 1 new review", async () => {
// Click the button to show update form // Click the button to create a new review
let create_btn = await page.$("#create-btn"); let create_btn = await page.$("#create-btn");
await create_btn.click(); await create_btn.click();
await page.waitForNavigation(); await page.waitForNavigation();
// Set text fields // create a new review
await page.$eval("#mealImg", el => el.value = "sample src"); let review = {
await page.$eval("#imgAlt", el => el.value = "sample alt"); imgAlt: "sample alt",
await page.$eval("#mealName", el => el.value = "sample name"); mealName: "sample name",
await page.$eval("#comments", el => el.value = "sample comment"); comments: "sample comment",
await page.$eval("#restaurant", el => el.value = "sample restaurant"); restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
// Get the button needed to add new tags rating: 1
let tag_btn = await page.$("#tag-add-btn"); };
for(let i = 0; i < 5; i++){ await setReviewForm(page, review);
await page.$eval("#tag-form", (el, value) => el.value = `tag ${value}`, i);
await tag_btn.click();
}
// 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 // Click the save button to save updates
let save_btn = await page.$("#save-btn"); let save_btn = await page.$("#save-btn");
@ -67,38 +64,17 @@ describe("test App end to end", async () => {
}); });
it("check details page", async () => { it("check details page", async () => {
// Get the review image and check src and alt // check the details page for correctness
let img = await page.$("#d-mealImg"); let expected = {
let imgSrc = await img.getProperty("src"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgAlt = await img.getProperty("alt"); imgAlt: "sample alt",
// Check src and alt mealName: "sample name",
assert.strictEqual(await imgSrc.jsonValue(), "sample src"); comments: "sample comment",
assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
// Get the title, comment, and restaurant rating: "http://localhost:8080/assets/images/icons/1-star.svg"
let title = await page.$("#d-mealName"); };
let title_text = await title.getProperty("innerText"); await checkCorrectness(page, "d", expected);
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(), "./assets/images/icons/5-star.svg");
}); });
it("check home page", async () => { it("check home page", async () => {
@ -111,37 +87,16 @@ describe("test App end to end", async () => {
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot"); let shadowRoot = await review_card.getProperty("shadowRoot");
// Get the review image and check src and alt let expected = {
let img = await shadowRoot.$("#a-mealImg"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgSrc = await img.getProperty("src"); imgAlt: "sample alt",
let imgAlt = await img.getProperty("alt"); mealName: "sample name",
// Check src and alt comments: "sample comment",
assert.strictEqual(await imgSrc.jsonValue(), "sample src"); restaurant: "sample restaurant",
assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: "http://localhost:8080/assets/images/icons/1-star.svg"
// Get the title, comment, and restaurant };
let title = await shadowRoot.$("#a-mealName"); await checkCorrectness(shadowRoot, "a", expected);
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(), "./assets/images/icons/5-star.svg");
}); });
}); });
@ -154,42 +109,20 @@ describe("test App end to end", async () => {
it("check details page", async () => { it("check details page", async () => {
// click review card // click review card
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
console.log(JSON.stringify(review_card));
await review_card.click(); await review_card.click();
await page.waitForNavigation(); await page.waitForNavigation();
// Get the review image and check src and alt // check the details page for correctness
let img = await page.$("#d-mealImg"); let expected = {
let imgSrc = await img.getProperty("src"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgAlt = await img.getProperty("alt"); imgAlt: "sample alt",
// Check src and alt mealName: "sample name",
assert.strictEqual(await imgSrc.jsonValue(), "sample src"); comments: "sample comment",
assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
// Get the title, comment, and restaurant rating: "http://localhost:8080/assets/images/icons/1-star.svg"
let title = await page.$("#d-mealName"); };
let title_text = await title.getProperty("innerText"); await checkCorrectness(page, "d", expected);
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(), "./assets/images/icons/5-star.svg");
}); });
it("check home page", async () => { it("check home page", async () => {
@ -202,37 +135,17 @@ describe("test App end to end", async () => {
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot"); let shadowRoot = await review_card.getProperty("shadowRoot");
// Get the review image and check src and alt // check the details page for correctness
let img = await shadowRoot.$("#a-mealImg"); let expected = {
let imgSrc = await img.getProperty("src"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgAlt = await img.getProperty("alt"); imgAlt: "sample alt",
// Check src and alt mealName: "sample name",
assert.strictEqual(await imgSrc.jsonValue(), "sample src"); comments: "sample comment",
assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
// Get the title, comment, and restaurant rating: "http://localhost:8080/assets/images/icons/1-star.svg"
let title = await shadowRoot.$("#a-mealName"); };
let title_text = await title.getProperty("innerText"); await checkCorrectness(shadowRoot, "a", expected);
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(), "./assets/images/icons/5-star.svg");
}); });
}); });
@ -242,7 +155,6 @@ describe("test App end to end", async () => {
// Get the only review card and click it // Get the only review card and click it
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
console.log(JSON.stringify(review_card));
await review_card.click(); await review_card.click();
await page.waitForNavigation(); await page.waitForNavigation();
@ -250,29 +162,16 @@ describe("test App end to end", async () => {
let update_btn = await page.$("#update-btn"); let update_btn = await page.$("#update-btn");
await update_btn.click(); await update_btn.click();
// Set text fields // create a new review
await page.$eval("#mealImg", el => el.value = "updated src"); let review = {
await page.$eval("#imgAlt", el => el.value = "updated alt"); imgAlt: "updated alt",
await page.$eval("#mealName", el => el.value = "updated name"); mealName: "updated name",
await page.$eval("#comments", el => el.value = "updated comment"); comments: "updated comment",
await page.$eval("#restaurant", el => el.value = "updated restaurant"); restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
// Get all tag elements and click them to delete them rating: 5
let tag_items = await page.$$(".tag"); };
for(let i = 0; i < tag_items.length; i++){ await setReviewForm(page, review);
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_selects.click();
// Click the save button to save updates // Click the save button to save updates
let save_btn = await page.$("#save-btn"); let save_btn = await page.$("#save-btn");
@ -281,37 +180,17 @@ describe("test App end to end", async () => {
}); });
it("check details page", async () => { it("check details page", async () => {
// Get the review image and check src and alt // check the details page for correctness
let img = await page.$("#d-mealImg"); let expected = {
let imgSrc = await img.getProperty("src"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgAlt = await img.getProperty("alt"); imgAlt: "updated alt",
// Check src and alt mealName: "updated name",
assert.strictEqual(await imgSrc.jsonValue(), "updated src"); comments: "updated comment",
assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
// Get the title, comment, and restaurant rating: "http://localhost:8080/assets/images/icons/5-star.svg"
let title = await page.$("#d-mealName"); };
let title_text = await title.getProperty("innerText"); await checkCorrectness(page, "d", expected);
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(), "./assets/images/icons/1-star.svg");
}); });
it("check home page", async () => { it("check home page", async () => {
@ -324,48 +203,33 @@ describe("test App end to end", async () => {
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot"); let shadowRoot = await review_card.getProperty("shadowRoot");
// Get the review image and check src and alt // check the details page for correctness
let img = await shadowRoot.$("#a-mealImg"); let expected = {
let imgSrc = await img.getProperty("src"); imgSrc: "http://localhost:8080/assets/images/icons/plate_with_cutlery.png",
let imgAlt = await img.getProperty("alt"); imgAlt: "updated alt",
// Check src and alt mealName: "updated name",
assert.strictEqual(await imgSrc.jsonValue(), "updated src"); comments: "updated comment",
assert.strictEqual(await imgAlt.jsonValue(), "updated alt"); restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
// Get the title, comment, and restaurant rating: "http://localhost:8080/assets/images/icons/5-star.svg"
let title = await shadowRoot.$("#a-mealName"); };
let title_text = await title.getProperty("innerText"); await checkCorrectness(shadowRoot, "a", expected);
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(), "./assets/images/icons/1-star.svg");
}); });
}); });
describe("test delete 1 review", () => { describe("test delete 1 review", async () => {
it("delete 1 review", async () => { it("delete 1 review", async () => {
// Get the only review card and click it // Get the only review card and click it
let review_card = await page.$("review-card"); let review_card = await page.$("review-card");
await review_card.click(); await review_card.click();
await page.waitForNavigation(); await page.waitForNavigation();
page.on("dialog", async dialog => {
console.log(dialog.message());
await dialog.accept();
});
// Get the delete button and click it // Get the delete button and click it
let delete_btn = await page.$("#delete-btn"); let delete_btn = await page.$("#delete-btn");
await delete_btn.click(); await delete_btn.click();
@ -377,6 +241,8 @@ describe("test App end to end", async () => {
}); });
}); });
});
after(async () => { after(async () => {
await page.close(); await page.close();
await browser.close(); await browser.close();

View File

@ -18,12 +18,12 @@ function init() {
* @param {Array<Object>} reviews An array of reviews * @param {Array<Object>} reviews An array of reviews
*/ */
function addReviewsToDocument(reviews) { function addReviewsToDocument(reviews) {
let mainEl = document.querySelector("main"); let box = document.getElementById("review-container");
reviews.forEach(review => { reviews.forEach(review => {
let newReview = document.createElement("review-card"); let newReview = document.createElement("review-card");
newReview.data = review; newReview.data = review;
//TODO: want to append it to whatever the box is in layout //TODO: want to append it to whatever the box is in layout
mainEl.append(newReview); box.append(newReview);
}); });
} }

View File

@ -13,14 +13,39 @@
<!-- Main Stylesheets & Scripts --> <!-- Main Stylesheets & Scripts -->
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config--> <!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
<!-- <link rel="stylesheet" href="/static/reset.css" /> --> <!-- <link rel="stylesheet" href="/static/reset.css" /> -->
<link rel="stylesheet" href="./static/ReviewCard.css" /> <link rel="stylesheet" href="./static/homepage.css" />
<script src="assets/scripts/main.js" type="module"></script> <script src="assets/scripts/main.js" type="module"></script>
</head> </head>
<body> <body>
<div class ="Top-Bar">
<img src ="./assets/images/icons/Logo.png" alt="logo" />
<h1 style="font-family:'Lucida Sans'"> Food Journal </h1>
<form id="form">
<input type='search' id="seaching" name="searchBar" placeholder="Search journal...">
<button class="click" type="search">
Search
</button>
</form>
<!--
<form id="form">
<input type='search' id="seaching" name="searchBar" placeholder="Search journal...">
<button class="click" type="search">
Search
</button>
</form>
--->
<main> <main>
<!-- Add Food Entries Here --> <!-- Add Food Entries Here -->
<div class="Review-boxes">
<h2> Recent Reviews </h2>
<img src ="./assets/images/icons/Grouppink.png" alt="CREATE" id="create-btn" onclick="window.location.assign('./CreatePage.html')"></img>
</div>
<div class="Filter-box">
</div>
<div class="review-container" id="review-container"></div>
</main> </main>
<button type="button" id="create-btn"><a href='./CreatePage.html'></a>CREATE</button> <!--<button type="button" id="create-btn"><a href='./CreatePage.html'></a>CREATE</button>-->
</body> </body>
</html> </html>

View File

@ -1,83 +1,84 @@
/* CreatePage.css */ /* CreatePage.css */
* {
font-family: sans-serif;
}
body{ body{
height: 100%; background-color: #13323b;
width: 100%;
} }
fieldset { h1 {
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;
text-align: center; 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 { .journal-form {
color: red; font-size: 120%;
width: 50%;
display: block;
margin: auto;
color: #ccb3bb;
border: 3px solid rgb(7, 0, 0);
background-color: #b52754;
} }
.danger { .hidden,
background-color: rgb(254 171 171); .rating:not(:checked) > input { /* Hide radio circles while star rating */
border-color: red; 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;
} }

View File

@ -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;
}

View File

@ -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.

View File

@ -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.