mirror of
				https://github.com/cse110-fa22-group29/cse110-fa22-group29.git
				synced 2025-10-30 19:46:49 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/sprint-2' into allow-for-user-uploaded-images
This commit is contained in:
		
							
								
								
									
										2
									
								
								.github/workflows/css-linting.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/css-linting.yml
									
									
									
									
										vendored
									
									
								
							| @@ -20,4 +20,4 @@ jobs: | ||||
|       - name: Install dependencies | ||||
|         run: sudo npm install | ||||
|       - name: Run tests | ||||
|         run: sudo npm run lintCSS | ||||
|         run: sudo npm run lint-css | ||||
							
								
								
									
										2
									
								
								.github/workflows/html-linting.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/html-linting.yml
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/js-linting.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/js-linting.yml
									
									
									
									
										vendored
									
									
								
							| @@ -22,4 +22,4 @@ jobs: | ||||
|       - name: Install dependencies | ||||
|         run: sudo npm install | ||||
|       - name: Run tests | ||||
|         run: sudo npm run lint | ||||
|         run: sudo npm run lint-js | ||||
| @@ -1,3 +1,4 @@ | ||||
| { | ||||
| 	"extends": "stylelint-config-standard" | ||||
| 	"extends": "stylelint-config-standard", | ||||
| 	"ignore": ["inside-parens", "param", "value"] | ||||
| } | ||||
| @@ -1,2 +1,5 @@ | ||||
| # cse110-fa22-group29 | ||||
| [Team Page Link](https://github.com/cse110-fa22-group29/cse110-fa22-group29/blob/main/admin/team.md) | ||||
| # cse110-fa22-group29 | ||||
|  | ||||
| [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/) | ||||
| @@ -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 | ||||
| ## Planned Features and Timeline | ||||
|   | ||||
							
								
								
									
										47
									
								
								admin/meetings/111722-sprint2meeting1.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								admin/meetings/111722-sprint2meeting1.md
									
									
									
									
									
										Normal 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 | ||||
							
								
								
									
										36
									
								
								admin/meetings/112022-sprint2meeting3.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								admin/meetings/112022-sprint2meeting3.md
									
									
									
									
									
										Normal 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 | ||||
| @@ -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": { | ||||
|   | ||||
| @@ -14,42 +14,56 @@ | ||||
|   <!-- Main Stylesheets & Scripts --> | ||||
|   <!-- 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/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> | ||||
|  | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|   <input type="button" value="Home" id="home-btn" onclick="window.location.assign('./index.html')"> | ||||
|   <form id="new-food-entry"> | ||||
|     <fieldset> | ||||
|       <legend>Pic:</legend> | ||||
|       Choose Input type: | ||||
|   <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"> | ||||
|       <fieldset> | ||||
|         <legend>Pic:</legend> | ||||
|         Choose Input type: | ||||
|       <select id="select" name="select"> | ||||
|         <option value="file">File Upload</option> | ||||
|         <option value="url">From an URL</option> | ||||
|       </select> | ||||
|       <label for="mealImage" id="source"> | ||||
|         Source: | ||||
|         <input type="file" accept="image/*" id="mealImg" name="mealImg"> | ||||
|       </label> | ||||
|       <label for="image-alt"> | ||||
|         Alt Text: | ||||
|         <input type="text" id="imgAlt" name="imgAlt"> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|     <fieldset> | ||||
|  | ||||
|       <legend> Meal: </legend> | ||||
|       <label for="Meal: ">Meal: | ||||
|         <input type="text" id="mealName" name="mealName" required> | ||||
|       </label> | ||||
|       <label for="comments">Comments: | ||||
|         <br> | ||||
|         <textarea name="comments" id="comments"></textarea> | ||||
|       </label> | ||||
|     </fieldset> | ||||
|  | ||||
|           Source: | ||||
|           <input type="file" accept="image/*" id="mealImg" name="mealImg"> | ||||
|         </label> | ||||
|         <label for="image-alt"> | ||||
|           Alt Text: | ||||
|           <input type="text" id="imgAlt" name="imgAlt"> | ||||
|         </label> | ||||
|       </fieldset> | ||||
|       <fieldset> | ||||
|         <legend> Meal: </legend> | ||||
|         <label for="Meal: ">Meal: | ||||
|           <input type="text" id="mealName" name="mealName" required> | ||||
|         </label> | ||||
|         <label for="comments">Comments: | ||||
|           <br> | ||||
|           <textarea name="comments" id="comments"></textarea> | ||||
|         </label> | ||||
|       </fieldset> | ||||
|     <fieldset class="rating"> | ||||
|       <legend> Rating: </legend> | ||||
|       <input type="radio" id="s5" name="rating" value="5"/> <label for="s5" id="s5-select"> 5 stars </label> | ||||
| @@ -59,24 +73,25 @@ | ||||
|       <input type="radio" id="s1" name="rating" value="1"/> <label for="s1" id="s1-select"> 1 star </label> | ||||
|     </fieldset> | ||||
|  | ||||
|     <fieldset> | ||||
|       <legend>Other Info:</legend> | ||||
|       <label for="restaurant"> | ||||
|         Restaurant: | ||||
|         <input type="text" id="restaurant" name="restaurant" required> | ||||
|       </label> | ||||
|       <label for="tag-form"> | ||||
|         Tags: | ||||
|         <input type="text" id="tag-form" name="tag-form"> | ||||
|         <div class='tag-container' id="tag-container-form"> | ||||
|  | ||||
|       <fieldset> | ||||
|         <legend>Other Info:</legend> | ||||
|         <label for="restaurant"> | ||||
|           Restaurant: | ||||
|           <input type="text" id="restaurant" name="restaurant" required> | ||||
|         </label> | ||||
|         <label for="tag-form"> | ||||
|           Tags: | ||||
|           <input type="text" id="tag-form" name="tag-form"> | ||||
|           <div class='tag-container' id="tag-container-form"> | ||||
|         </div> | ||||
|         <button type="button" id="tag-add-btn">Add Tag</button> | ||||
|       </label> | ||||
|  | ||||
|     </fieldset> | ||||
|     <button type="submit" id="save-btn" value="Submit">Save Review</button> | ||||
|   </form> | ||||
|  | ||||
|       </fieldset> | ||||
|       <button type="submit" id="save-btn" value="Submit">Save Review</button> | ||||
|     </form> | ||||
|   </div>  | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| @@ -77,7 +77,7 @@ | ||||
|         </label> | ||||
|    | ||||
|       </fieldset> | ||||
|       <button type="submit" value="Submit">Add Review</button> | ||||
|       <button type="submit" id="save-btn" value="Submit">Add Review</button> | ||||
|       </form> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/Grouppink.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								source/assets/images/icons/Grouppink.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/Logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								source/assets/images/icons/Logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 13 KiB | 
							
								
								
									
										
											BIN
										
									
								
								source/assets/images/icons/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								source/assets/images/icons/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 16 KiB | 
							
								
								
									
										76
									
								
								source/assets/scripts/appTestHelpers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								source/assets/scripts/appTestHelpers.js
									
									
									
									
									
										Normal 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); | ||||
| } | ||||
| @@ -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,7 +18,8 @@ describe("test App end to end", async () => { | ||||
| 			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(); | ||||
| 		try{ | ||||
| 			await page.goto("http://localhost:8080", {timeout: 1000}); | ||||
| @@ -35,346 +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("#mealImg", el => el.value = "sample src"); | ||||
| 			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(); | ||||
| 			}); | ||||
|  | ||||
| 			// 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: "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"); | ||||
|  | ||||
| 				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); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		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(), "sample src"); | ||||
| 			assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); | ||||
| 		describe("test read 1 review after refresh", async () => { | ||||
| 			it("refresh page", async () => { | ||||
| 				// Reload the page | ||||
| 				await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); | ||||
| 			}); | ||||
|  | ||||
| 			// 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"); | ||||
| 			it("check details page", async () => { | ||||
| 				// click review card | ||||
| 				let review_card = await page.$("review-card"); | ||||
| 				await review_card.click(); | ||||
| 				await page.waitForNavigation(); | ||||
|  | ||||
| 			// 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 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); | ||||
| 			}); | ||||
|  | ||||
| 			// 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}`); | ||||
| 			} | ||||
| 			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 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 () => { | ||||
| 			// 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 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(), "sample src"); | ||||
| 			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(), "./assets/images/icons/5-star.svg"); | ||||
| 		}); | ||||
| 	}); | ||||
|  | ||||
| 	describe("test read 1 review after refresh", async () => { | ||||
| 		it("refresh page", async () => { | ||||
| 			// Reload the page | ||||
| 			await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] }); | ||||
| 				// 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); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		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(); | ||||
| 		describe("test update 1 review", 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(), "sample src"); | ||||
| 			assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); | ||||
| 			it("update 1 review", async () => { | ||||
|  | ||||
| 			// 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"); | ||||
| 				// Get the only review card and click it | ||||
| 				let review_card = await page.$("review-card"); | ||||
| 				await review_card.click(); | ||||
| 				await page.waitForNavigation(); | ||||
|  | ||||
| 			// 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"); | ||||
| 				// Click the button to show update form | ||||
| 				let update_btn = await page.$("#update-btn"); | ||||
| 				await update_btn.click(); | ||||
|  | ||||
| 			// 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}`); | ||||
| 			} | ||||
| 				// 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); | ||||
| 			}); | ||||
|  | ||||
| 			// 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 () => { | ||||
| 			// Click the button to return to the home page | ||||
| 			let home_btn = await page.$("#home-btn"); | ||||
| 			home_btn.click(); | ||||
| 			await page.waitForNavigation(); | ||||
| 		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"); | ||||
| 				await review_card.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"); | ||||
| 				page.on("dialog", async dialog => { | ||||
| 					console.log(dialog.message()); | ||||
| 					await dialog.accept(); | ||||
| 				}); | ||||
|  | ||||
| 			// 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(), "sample src"); | ||||
| 			assert.strictEqual(await imgAlt.jsonValue(), "sample alt"); | ||||
| 				// Get the delete button and click it | ||||
| 				let delete_btn = await page.$("#delete-btn"); | ||||
| 				await delete_btn.click(); | ||||
| 				await page.waitForNavigation(); | ||||
|  | ||||
| 			// 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(), "./assets/images/icons/5-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"); | ||||
| 			console.log(JSON.stringify(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("#mealImg", el => el.value = "updated src"); | ||||
| 			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_selects.click(); | ||||
|  | ||||
| 			// Click the save button to save updates | ||||
| 			let save_btn = await page.$("#save-btn"); | ||||
| 			await save_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); | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		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(), "updated src"); | ||||
| 			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(), "./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(), "updated src"); | ||||
| 			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(), "./assets/images/icons/1-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(); | ||||
|  | ||||
| 			// 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 () => { | ||||
|   | ||||
| @@ -18,12 +18,12 @@ function init() { | ||||
|  * @param {Array<Object>} 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); | ||||
| 	}); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -13,14 +13,39 @@ | ||||
|   <!-- Main Stylesheets & Scripts -->  | ||||
|   <!-- 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/ReviewCard.css" /> | ||||
|   <link rel="stylesheet" href="./static/homepage.css" /> | ||||
|   <script src="assets/scripts/main.js" type="module"></script> | ||||
|  | ||||
| </head> | ||||
| <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> | ||||
|     <!-- 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> | ||||
|   <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> | ||||
| </html> | ||||
|   | ||||
| @@ -1,83 +1,84 @@ | ||||
| /* 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; | ||||
| .journal-form { | ||||
|   font-size: 120%; | ||||
|   width: 50%; | ||||
|   display: block; | ||||
|   margin: auto; | ||||
|   color: #ccb3bb; | ||||
|   border: 3px solid rgb(7, 0, 0); | ||||
|   background-color: #b52754; | ||||
| } | ||||
|  | ||||
| .danger { | ||||
|   background-color: rgb(254 171 171); | ||||
|   border-color: red; | ||||
| .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; | ||||
| } | ||||
							
								
								
									
										65
									
								
								source/static/homepage.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								source/static/homepage.css
									
									
									
									
									
										Normal 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; | ||||
|   } | ||||
							
								
								
									
										19
									
								
								specs/adrs/111422-csslinting-stylelint.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								specs/adrs/111422-csslinting-stylelint.md
									
									
									
									
									
										Normal 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.  | ||||
							
								
								
									
										19
									
								
								specs/adrs/111422-htmllinting-htmlhint.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								specs/adrs/111422-htmllinting-htmlhint.md
									
									
									
									
									
										Normal 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.  | ||||
		Reference in New Issue
	
	Block a user