diff --git a/jest-puppeteer.config.cjs b/jest-puppeteer.config.cjs index 49558e6..db455d1 100644 --- a/jest-puppeteer.config.cjs +++ b/jest-puppeteer.config.cjs @@ -1,7 +1,7 @@ module.exports = { - launch: { - headless: false, /* Change to false if you want to see the tests run on a browser */ - slowMo: 10, - defaultViewport: null + launch: { // On launch + headless: false, // Change to false if you want to see the tests run on a browser + slowMo: 10, // Controls how quickly tests are run + defaultViewport: null // Allows us to modify viewport in tests } } \ No newline at end of file diff --git a/source/calendar/calendar.html b/source/calendar/calendar.html index a828eb6..dd6c013 100644 --- a/source/calendar/calendar.html +++ b/source/calendar/calendar.html @@ -17,14 +17,16 @@
+
+

Tasks

+ -
@@ -36,10 +38,12 @@

Tasks

+
+
@@ -59,8 +63,8 @@

Tasks

+
- -
diff --git a/source/calendar/calendar.js b/source/calendar/calendar.js index 9c42f44..7c7c5a5 100644 --- a/source/calendar/calendar.js +++ b/source/calendar/calendar.js @@ -10,13 +10,17 @@ var currDate = new Date(); var month = currDate.getMonth(); var year = currDate.getFullYear(); -// Update the global date variables +/** + * Updates the global date variables to the current date. + */ function updateDateGlobals() { month = currDate.getMonth(); year = currDate.getFullYear(); } -// When page loads +/** + * Initializes the page when the DOM content is fully loaded. + */ function init() { // Initiaze the jump buttons displayJump(year - 6, year + 5); @@ -33,7 +37,9 @@ function init() { // FUNCTIONS - +/** + * Initializes the buttons for adding tasks, navigating months, and other functionalities. + */ function initButtons() { const addTaskBtn = document.querySelector(".add-task-btn"); @@ -50,6 +56,7 @@ function initButtons() { nextBtn.addEventListener('click', next); // JUMP HEADER BUTTONS + // LIST OF MONTHS let monthJumpBtn = document.querySelectorAll(".month-btn"); monthJumpBtn.forEach(btn => { btn.addEventListener("click", () => { @@ -57,6 +64,7 @@ function initButtons() { jump(monthValue, year); }); }); + // LIST OF YEARS let yearJumpBtn = document.querySelectorAll(".year-btn"); yearJumpBtn.forEach(btn => { btn.addEventListener("click", () => { @@ -88,7 +96,9 @@ function next(){ displayCalendar(); } -// Function to goto previous month +/** + * Updates the global currDate to the previous month and displays the previous month's calendar. + */ function prev() { // Decrement the month currDate.setMonth(currDate.getMonth() - 1); @@ -97,12 +107,16 @@ function prev() { } /** - * Adds task to task list upon "Add Task" button click. + * Adds a task to the task list upon "Add Task" button click. + * @param {boolean} [loadTask=false] - Indicates whether the task is being loaded from storage. + * @returns {HTMLElement} - The newly created task element. */ function addTask(loadTask = false) { + // add a task to an element of task container const taskList = document.querySelector(".task-container"); const task = document.createElement("li"); task.setAttribute("class", "task"); + // add it at the first row task.insertAdjacentHTML("beforeend", `
@@ -154,8 +168,8 @@ function addTask(loadTask = false) { } /** - * Adds button functionality to task upon creation - * @param {Task Node} task - the task to have functionality + * Adds button functionality to a task upon creation. + * @param {HTMLElement} task - The task element to add functionality to. */ function taskButtonsFunctionality(task) { @@ -216,7 +230,8 @@ function taskButtonsFunctionality(task) { } /** - * Saves the completed tasks per day + * Saves the completed tasks for a specific day. + * @param {HTMLElement} completedTaskElement - The task element that was completed. */ function saveCompleted(completedTaskElement) { let data = getJournal(); @@ -233,7 +248,9 @@ function saveCompleted(completedTaskElement) { displayCalendar(); } -// Function to display the calendar +/** + * Displays the calendar for the current month. + */ function displayCalendar() { // Get body and clear current calendar let tbody = document.getElementById("tbody-calendar"); @@ -329,6 +346,11 @@ function displayCalendar() { document.getElementById('year-dropdown').style.left = monthWidth + 5 + 'px'; } +/** + * Loads cell data such as rating, productivity, and tasks for a specific date in the calendar. + * @param {HTMLElement} cellData - The table cell element to populate with data. + * @param {Date} currCalendarMonth - The current month being displayed in the calendar. + */ function loadCellDataTest(cellData, currCalendarMonth) { let journals = getJournal(); let dateText = currCalendarMonth.toLocaleDateString(); @@ -401,7 +423,11 @@ function loadCellDataTest(cellData, currCalendarMonth) { cellData.appendChild(aLink); } -// Generate dropdown year range +/** + * Generates a dropdown for year and month selection. + * @param {number} startYear - The start year for the dropdown range. + * @param {number} endYear - The end year for the dropdown range. + */ function displayJump(startYear, endYear) { // YEARS let yearDropdown = document.getElementById("year-dropdown") @@ -463,7 +489,9 @@ function calendarHeader(){ thead.appendChild(headerRow); } -// Resize header if width of window decreases +/** + * Adjusts the month header text based on the window width. + */ function windowWidth() { if (window.innerWidth < 920) { // Initialize list of abbreviated months @@ -523,13 +551,12 @@ function saveToStorage(data, dateText, key, value) { } /** - * Load journal entry from local storage - * - * @param {string} data - journal entry text in parsed json format - * @param {string} dateText - date of the journal entry in locale date string format - * @param {string} key - key to get the value from + * Load journal entry from local storage. * - * @returns {string} value of the key in the data + * @param {Object} data - Journal entry text in parsed JSON format. + * @param {string} dateText - Date of the journal entry in locale date string format. + * @param {string} key - Key to get the value from. + * @returns {string|null} - Value of the key in the data or null if not found. */ function loadFromStorage(data, dateText, key) { if (!(dateText in data)) { @@ -596,4 +623,4 @@ function loadTasks() { // Save journal entry and tasks to local storage on events tasks.addEventListener("blur", saveTasks) -tasks.addEventListener("change", saveTasks) +tasks.addEventListener("change", saveTasks) \ No newline at end of file diff --git a/source/homepage/homepage.html b/source/homepage/homepage.html index fea806c..bc38575 100644 --- a/source/homepage/homepage.html +++ b/source/homepage/homepage.html @@ -17,14 +17,16 @@
+
+

Tasks

+ -
@@ -33,59 +35,55 @@

Tasks

- + +
+
+

Journal

+
+
- +

How's your mental health today?

@@ -111,26 +109,33 @@

How's your mental health today?

+

How productive are you feeling today?

+ + + + +
-
+ +

Tasks Completed Today

@@ -139,11 +144,13 @@

Tasks Completed Today

+
+
@@ -153,4 +160,4 @@

Tasks Completed Today

- + \ No newline at end of file diff --git a/source/homepage/homepage.js b/source/homepage/homepage.js index 05e6cc5..523cc81 100644 --- a/source/homepage/homepage.js +++ b/source/homepage/homepage.js @@ -19,7 +19,7 @@ function init() { displayWeek(); initButtons(); - clickTaskList(); + taskListViewHandler(); } @@ -96,6 +96,7 @@ function prevDate() { unselectAllCompleted(); loadAll(); } + /** * Formats the currDate global variable into proper string display * @returns {string} - properly formatted string representing the date as "Weekday, Month Day, Year" @@ -136,7 +137,8 @@ function selectWidget(buttonIndex) { } /** - * Adds task to task list upon "Add Task" button click. + * Adds task to task list upon "Add Task" button click. Initializes buttons within each task + * @param {boolean} [loadTask=false] */ function addTask(loadTask = false) { const taskList = document.querySelector(".task-container"); @@ -161,7 +163,7 @@ function selectWidget(buttonIndex) { taskList.append(task); - // listener to stop editing when user presses enter + // Listener to stop editing when user presses enter const task_name = task.querySelector(".task-input"); task_name.addEventListener('keydown', function (event) { if (event.key == 'Enter') { @@ -170,7 +172,6 @@ function selectWidget(buttonIndex) { // Enter pressed, end editing event.preventDefault(); // Prevent default behavior of Enter key task_name.blur(); // Remove focus from the element - //li.classList.remove('active'); } } }); @@ -198,7 +199,7 @@ function selectWidget(buttonIndex) { /** * Adds button functionality to task upon creation - * @param {Task Node} task - the task to have functionality + * @param {HTMLElement} task - the task to have functionality */ function taskButtonsFunctionality(task) { @@ -318,19 +319,16 @@ function displayWeek() { // Append cell number to new cell cellData.appendChild(cellNum); - - loadCellDataTest(cellData, currWeekDay); + loadCellData(cellData, currWeekDay); // Append new cell to row row.appendChild(cellData); } // Append row to table table.appendChild(row); - } -//------------------------------------------ -// Save journal entry +/* ******** Storage and Population ********** */ // Get the all relevent elements from page const journal = document.getElementById("textarea"); @@ -351,16 +349,8 @@ window.onbeforeunload = function () { saveCompleted() } -// const AUTO_SAVE_INTERVAL = 30000; -// Save journal entry and tasks to local storage on timer -// Save every 30 seconds -// var saveInterval = setInterval(function(){ -// saveJournal() -// saveTasks() -// }, AUTO_SAVE_INTERVAL) - /** - * Save journal entry to local storage + * Format journal input to be stored * * @param {string} data - journal entry text in parsed json format * @param {string} dateText - date of the journal entry in locale date string format @@ -459,21 +449,11 @@ function loadTasks() { let curLi = addTask(true); curLi.querySelector(".task-input").textContent = task['text'] curLi.style['background-color'] = task['color'] - //curLi.querySelector('input[type="checkbox"]').checked = task['checked'] }); } } -/* -function saveJournal() { - let data = getJournal() - let dateText = new Date(date.textContent).toLocaleDateString(); - saveToStorage(data, dateText, "contents", journal.value) - localStorage.setItem("journals", JSON.stringify(data)) -} - */ - /** * Saves the completed tasks per day */ @@ -494,6 +474,11 @@ function saveCompleted() { displayWeek(); } +/** + * Fetch completed tasks from storage in proper format + * + * @returns {string} tasks data in proper format + */ function getCompleted() { let data = getJournal(); let dateText = new Date(date.textContent).toLocaleDateString(); @@ -502,7 +487,7 @@ function getCompleted() { } /** - * Load tasks from local storage + * Load and populate completed tasks from local storage */ function loadCompleted() { let tasks2 = getCompleted(); @@ -518,9 +503,11 @@ function loadCompleted() { } } +/** + * Remove completed tasks from interface upon changing dates + */ function unselectAllCompleted() { document.querySelectorAll('.completed-task-container li').forEach(task => { - //let checkbox = task.querySelector('input[type="task-checkbox"]'); task.remove(); }); } @@ -528,8 +515,7 @@ function unselectAllCompleted() { /** * Save widgets to local storage * - * @param {int} value - value of the widget selected: - * 1-5 for mental health, 6-10 for productivity + * @param {int} value - ID value of the widget selected */ function saveWidgets(value) { let data = getJournal(); @@ -545,7 +531,7 @@ function saveWidgets(value) { } /** - * Load widgets from local storage + * Load widget ratings from local storage */ function loadWidgets() { let data = getJournal(); @@ -569,7 +555,12 @@ function loadAll() { loadCompleted(); } -function loadCellDataTest(cellData, currWeekDay) { +/** + * + * @param {HTMLElement} cellData - Data for specified day + * @param {Date} currWeekDay - Date to populate data within + */ +function loadCellData(cellData, currWeekDay) { let journals = getJournal(); let dateText = currWeekDay.toLocaleDateString(); @@ -654,7 +645,10 @@ function dateQuery() { } } -function clickTaskList() { +/** + * + */ +function taskListViewHandler() { const taskList = document.querySelector('.task-list'); const taskWrap = document.querySelector('.task-wrapper'); const outSide = document.querySelector('.main-wrap'); @@ -675,12 +669,12 @@ function clickTaskList() { } // Save journal entry and tasks to local storage on events -journal.addEventListener("blur", saveJournal) -tasks.addEventListener("blur", saveTasks) -tasks.addEventListener("change", saveTasks) -tasks.addEventListener("blur", saveCompleted) -tasks.addEventListener("change", saveCompleted) -completedTasks.addEventListener("blur", saveCompleted) -completedTasks.addEventListener("change", saveCompleted) -completedTasks.addEventListener("blur", saveTasks) -completedTasks.addEventListener("change", saveTasks) \ No newline at end of file +journal.addEventListener("blur", saveJournal); +tasks.addEventListener("blur", saveTasks); +tasks.addEventListener("change", saveTasks); +tasks.addEventListener("blur", saveCompleted); +tasks.addEventListener("change", saveCompleted); +completedTasks.addEventListener("blur", saveCompleted); +completedTasks.addEventListener("change", saveCompleted); +completedTasks.addEventListener("blur", saveTasks); +completedTasks.addEventListener("change", saveTasks); \ No newline at end of file diff --git a/testing/puppeteer.test.js b/testing/puppeteer.test.js index 54dd09e..0bbbe99 100644 --- a/testing/puppeteer.test.js +++ b/testing/puppeteer.test.js @@ -174,66 +174,85 @@ describe('Homepage task list tests', () => { it('Add a task, set its title, and choose a color', async () => { console.log('Testing task addition, title setting, and color selection...'); + // Setting the viewport size for the page await page.setViewport({ width: 1200, height: 800 }); - + + // Clicking the button to add a new task await page.click('.add-task-btn'); + // Selector for the input field of the newly added task const taskInputSelector = '.task-container .task:last-child .task-input'; await page.waitForSelector(taskInputSelector); const taskInput = await page.$(taskInputSelector); + // Typing the title for the new task const taskTitle = 'New Task Title for Testing'; await taskInput.type(taskTitle); + // Selector for the color button and choosing a color const colorButton = '.task-container .task:last-child .color-buttons'; const colorButtonSelector = '.task-container .task:last-child .color-button'; await page.hover(colorButton); await page.click(colorButtonSelector); + // Evaluating and retrieving the entered title from the DOM const enteredTitle = await page.evaluate(selector => { return document.querySelector(selector).textContent; }, taskInputSelector); + // Evaluating and retrieving the background color of the new task const backgroundColor = await page.evaluate(selector => { const task = document.querySelector(selector); return window.getComputedStyle(task).backgroundColor; }, '.task-container .task:last-child'); + // Asserting that the entered title matches the expected title expect(enteredTitle).toBe(taskTitle); - expect(backgroundColor).toBe('rgb(195, 128, 204)'); + + // Asserting that the background color matches the expected color + expect(backgroundColor).toBe('rgb(195, 128, 204)'); }); - - it('Edit the task and delete it', async() => { + + it('Edit the task and delete it', async () => { + // Selector for the input field of the last task const taskInputSelector = '.task-container .task:last-child .task-input'; await page.waitForSelector(taskInputSelector); const taskInput = await page.$(taskInputSelector); - + + // Clearing the current task title by pressing 'Backspace' multiple times for (let i = 0; i < 27; i++) { - await taskInput.press('Backspace'); + await taskInput.press('Backspace'); } - + + // Typing the new title for the task const taskTitle = 'Editing Task Title'; await taskInput.type(taskTitle); + // Hovering over the color button and selecting a new color const colorButton = '.task-container .task:last-child .color-buttons'; await page.hover(colorButton); - + await page.evaluate(() => { const colorButtonSelector = '.task-container .task:last-child .color-buttons #blue'; document.querySelector(colorButtonSelector).click(); - }); + }); + // Evaluating and retrieving the entered title from the DOM const enteredTitle = await page.evaluate(selector => { return document.querySelector(selector).textContent; }, taskInputSelector); + // Evaluating and retrieving the background color of the edited task const backgroundColor = await page.evaluate(selector => { const task = document.querySelector(selector); return window.getComputedStyle(task).backgroundColor; }, '.task-container .task:last-child'); + // Asserting that the entered title matches the expected title expect(enteredTitle).toBe(taskTitle); - expect(backgroundColor).toBe('rgb(107, 177, 217)'); + + // Asserting that the background color matches the expected color + expect(backgroundColor).toBe('rgb(107, 177, 217)'); }); // Resize the window to make the task-list slide out