Skip to content

Commit

Permalink
Refactor saveSignature and loadSignature methods to use TabSignature …
Browse files Browse the repository at this point in the history
…object
  • Loading branch information
ahmad-PH committed Feb 3, 2024
1 parent f96bcf0 commit d400a73
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 54 deletions.
17 changes: 9 additions & 8 deletions src/background/background.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { storageGet, storageSet } from "../utils";
import { Tab } from "../types";
import { loadSignature, saveSignature } from "./signatureStorage";
import { Tab, TabSignature } from "../types";
import { loadTab, saveTab } from "./signatureStorage";
import { getLogger } from "../log";
import { startTheGarbageCollector } from "./garbageCollector";
import { EVENT_OPEN_RENAME_DIALOG } from "../config";

const log = getLogger('background.js');
log.setLevel('DEBUG');
log.setLevel('WARN');

chrome.commands.onCommand.addListener((command) => {
if (command === EVENT_OPEN_RENAME_DIALOG) {
Expand All @@ -26,11 +26,12 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.command === "get_tab_info") {
sendResponse({ id: sender.tab.id, url: sender.tab.url, index: sender.tab.index});
} else if (message.command === "save_signature") {
saveSignature(sender.tab.id, sender.tab.url, sender.tab.index, message.title, message.favicon);
const tab = new Tab(sender.tab.id, sender.tab.url, sender.tab.index, false, null, message.signature);
saveTab(tab);
} else if (message.command === "load_signature") {
loadSignature(sender.tab.id, sender.tab.url, sender.tab.index, false)
.then((resp) => {
return sendResponse(resp);
loadTab(sender.tab.id, sender.tab.url, sender.tab.index, false)
.then((tab) => {
return sendResponse(tab.signature);
}).catch(e => {
log.error('Error while loading signature:', e);
return sendResponse(null);
Expand All @@ -57,7 +58,7 @@ chrome.tabs.onRemoved.addListener(async function(tabId, removeInfo) {

chrome.tabs.onCreated.addListener(async (tab) => {
log.debug('onCreated called:', tab);
const signature = await loadSignature(tab.id, tab.url, tab.index, true);
const signature = (await loadTab(tab.id, tab.url, tab.index, true)).signature;
log.debug('found this info:', signature);
if (signature) {
chrome.tabs.sendMessage(tab.id, {
Expand Down
29 changes: 13 additions & 16 deletions src/background/signatureStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Tab, TabSignature } from "../types";
import { storageGet, storageSet } from "../utils";
import { getLogger } from "../log";

const log = getLogger('signatureStorage.js')
const log = getLogger('signatureStorage.js');
// log.setLevel('DEBUG');

/**
Expand Down Expand Up @@ -54,8 +54,9 @@ function findMatchingTab(storedTabInfo, tabId, url, index) {
* @param {string} url
* @param {number} index
* @param {boolean} isBeingOpened
* @returns {Promise<Tab|null>} The tab matching the given information.
*/
async function loadSignature(tabId, url, index, isBeingOpened) {
async function loadTab(tabId, url, index, isBeingOpened) {
// Put a descriptive log logging everyhting with its name:
log.debug('tabId:', tabId, 'url:', url, 'index:', index, 'isBeingOpened:', isBeingOpened);
const storedTabInfo = await storageGet(null);
Expand All @@ -72,27 +73,23 @@ async function loadSignature(tabId, url, index, isBeingOpened) {
matchedTabInfo.closedAt = null;
}
await storageSet({[tabId]: matchedTabInfo});
return matchedTabInfo.signature;
return matchedTabInfo;
} else {
log.debug('No matched tab info found');
return null;
}
}

/**
* @param {number} tabId
* @param {string} url
* @param {number} index
* @param {string} title
* @param {string} favicon
* @param {Tab} tab
*/
async function saveSignature(tabId, url, index, title, favicon) {
async function saveTab(tab) {
log.debug('Function called: saveSignature');
log.debug('tabId, url, index, title, favicon:', tabId, url, index, title, favicon);
log.debug('tab:', tab);
/** @type {Tab} */
const result = await storageGet(tabId);
const result = await storageGet(tab.id);
log.debug('result retrieved:', result);
let newSignature = new TabSignature(null, null);
let newSignature = new TabSignature(null, null, null);
let isClosed = false, closedAt = null;
if (result) {
log.debug('result id:', result);
Expand All @@ -104,13 +101,13 @@ async function saveSignature(tabId, url, index, title, favicon) {
isClosed = result.isClosed;
closedAt = result.closedAt;
}
newSignature.title = title || newSignature.title;
newSignature.favicon = favicon || newSignature.favicon;
newSignature.title = tab.signature.title || newSignature.title;
newSignature.favicon = tab.signature.favicon || newSignature.favicon;
log.debug('newSignature after possible overwrite with title and favicon:', newSignature);

await storageSet({[tabId]: new Tab(tabId, url, index, isClosed, closedAt, newSignature)});
await storageSet({[tab.id]: new Tab(tab.id, tab.url, tab.index, isClosed, closedAt, newSignature)});
log.debug('Data saved to storage');
}


export { findMatchingTab, loadSignature, saveSignature };
export { findMatchingTab, loadTab, saveTab };
11 changes: 9 additions & 2 deletions src/contentScript/backgroundScriptApi.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import log from "../log";
import { TabSignature } from "../types";

class BackgroundScriptAPI {
async saveSignature(title, favicon) {
/**
* @param {TabSignature} signature
*/
async saveSignature(signature) {
try {
await chrome.runtime.sendMessage({command: "save_signature", title, favicon});
await chrome.runtime.sendMessage({command: "save_signature", signature});
} catch (error) {
log.error('Failed to save signature:', error);
throw error;
}
}

/**
* @returns {Promise<TabSignature>}
*/
async loadSignature() {
try {
return await chrome.runtime.sendMessage({command: "load_signature"});
Expand Down
5 changes: 3 additions & 2 deletions src/contentScript/setters.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import log from "../log";
import { TabSignature } from "../types";
import { emojiToDataURL } from "../utils";
import bgScriptApi from "./backgroundScriptApi";
import { preserveFavicon, preserveTabTitle } from "./preservers";
Expand All @@ -9,7 +10,7 @@ export async function setTabTitle(newTabTitle, preserve = true) {
preserveTabTitle(newTabTitle);
}
document.title = newTabTitle;
await bgScriptApi.saveSignature(newTabTitle, null);
await bgScriptApi.saveSignature(new TabSignature(newTabTitle, null));
}

export async function setTabFavicon(favicon, preserve = true) {
Expand All @@ -27,7 +28,7 @@ export async function setTabFavicon(favicon, preserve = true) {
link.href = emojiDataURL;
document.getElementsByTagName('head')[0].appendChild(link);

await bgScriptApi.saveSignature(null, favicon);
await bgScriptApi.saveSignature(new TabSignature(null, favicon));
if (preserve) {
preserveFavicon(emojiDataURL);
}
Expand Down
12 changes: 7 additions & 5 deletions src/types.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export class Tab {
/**
* @param {number} id - The id of the tab.
* @param {string} url - The URL of the tab.
* @param {number} id
* @param {string} url
* @param {number} index - The index of the tab in the current window.
* @param {boolean} isClosed - Whether the tab is closed.
* @param {boolean} isClosed
* @param {string} closedAt - ISO string representing the time the tab was closed.
* @param {TabSignature} signature - The signature of the tab.
* @param {TabSignature} signature
*/
constructor(id, url, index, isClosed, closedAt, signature) {
this.id = id;
Expand All @@ -24,9 +24,11 @@ export class TabSignature {
/**
* @param {string} title
* @param {string} favicon
* @param {string} originalTitle
*/
constructor(title, favicon) {
constructor(title, favicon, originalTitle = null) {
this.title = title;
this.favicon = favicon;
this.originalTitle = originalTitle;
}
}
25 changes: 13 additions & 12 deletions tests/e2e/seleniumTests.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ describe('Selenium UI Tests', () => {
/** @type {DriverUtils|null} */
let driverUtils = null;

const googleURL = 'http://www.google.com';
const exampleURL = 'https://www.example.com';
// const natGeoURL = 'https://www.nationalgeographic.com/';
const url1 = 'https://www.google.com/';
// const url2 = 'https://www.example.com/';
// const url2 = 'https://www.nationalgeographic.com/';
const url2 = 'https://www.ahmadphosseini.com/';

const createNewDriver = async () => {
const extensionPath = process.env.EXTENSION_PATH || './dist/dev';
Expand All @@ -27,7 +28,7 @@ describe('Selenium UI Tests', () => {
driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(new chrome.Options()
.addArguments('--headless=new')
// .addArguments('--headless=new')
.addArguments(`--load-extension=${extensionPath}`)
.addArguments('user-data-dir=/tmp/chrome-profile')
)
Expand All @@ -46,27 +47,27 @@ describe('Selenium UI Tests', () => {
});

test('Can open dialog', async () => {
await driver.get(googleURL);
await driver.get(url1);
await driverUtils.openRenameDialog();
await driver.findElement(By.id(ROOT_ELEMENT_ID));
});

test('Can rename tab', async () => {
await driver.get(googleURL);
await driver.get(url1);
const newTitle = 'New Title';
await driverUtils.renameTab(newTitle);
const actualTitle = await driverUtils.getTitle();
expect(actualTitle).toBe(newTitle);
});

test('Can set emojis', async () => {
await driver.get(googleURL);
await driver.get(url1);
await driverUtils.setFavicon('😃');
await driverUtils.assertEmojiSetAsFavicon();
});

test('Retains tab signature when tab is re-opened', async () => {
const originalURL = googleURL;
const originalURL = url1;
await driver.get(originalURL);
const newTitle = 'New title', newFavicon = '🙃';

Expand Down Expand Up @@ -107,11 +108,11 @@ describe('Selenium UI Tests', () => {
*/
await driver.switchTo().newWindow('tab'); // dummy tab

await driver.get(googleURL);
await driver.get(url1);
const signature1 = { title: 'Title1', favicon: '😀' };
await driverUtils.setSignature(signature1.title, signature1.favicon);

await driverUtils.openTabToURL(exampleURL);
await driverUtils.openTabToURL(url2);

const signature2 = { title: 'Title2', favicon: '🌟' };
await driverUtils.setSignature(signature2.title, signature2.favicon);
Expand All @@ -122,11 +123,11 @@ describe('Selenium UI Tests', () => {
await driver.sleep(100);
await createNewDriver();

await driver.get(googleURL);
await driver.get(url1);
expect(await driverUtils.getTitle()).toBe(signature1.title);
await driverUtils.assertEmojiSetAsFavicon();

await driverUtils.openTabToURL(exampleURL);
await driverUtils.openTabToURL(url2);
expect(await driverUtils.getTitle()).toBe(signature2.title);
await driverUtils.assertEmojiSetAsFavicon();

Expand Down
18 changes: 9 additions & 9 deletions tests/unit/signatureStorage.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { findMatchingTab, loadSignature, saveSignature } = require('../../src/background/signatureStorage.js');
const { findMatchingTab, loadTab, saveTab } = require('../../src/background/signatureStorage.js');
const { Tab, TabSignature } = require('../../src/types.js');
const { storageSet, storageGet } = require('../../src/utils.js');
const { chromeStorageMock } = require('../chromeStorageMock.js');
Expand Down Expand Up @@ -65,7 +65,7 @@ describe('findMatchingTab', () => {
});


describe('save/loadSignature', () => {
describe('save/loadTab', () => {
beforeEach(() => {
global.chrome = chromeStorageMock;
chromeStorageMock.storage.sync.set.mockClear();
Expand All @@ -76,26 +76,26 @@ describe('save/loadSignature', () => {
delete global.chrome;
});

it('loadSignature updates isClosed after matching', async () => {
it('loadTab updates isClosed after matching', async () => {
await storageSet({1: new Tab(1, 'https://www.google.com', 5, true, null, new TabSignature('Google', '🔍'))});
expect((await storageGet(1)).isClosed).toBe(true);
await loadSignature(1, null, null, true);
await loadTab(1, null, null, true);
expect((await storageGet(1)).isClosed).toBe(false);
});

it('loadSignature can load signature saved with saveSignature', async () => {
await saveSignature(1, 'https://www.google.com', 5, 'Google', '🔍');
const signature = await loadSignature(1, null, null, false);
it('loadTab can load signature saved with saveTab', async () => {
await saveTab(new Tab(1, 'https://www.google.com', 5, false, null, new TabSignature('Google', '🔍')));
const signature = (await loadTab(1, null, null, false)).signature;
expect(signature.title).toBe('Google');
expect(signature.favicon).toBe('🔍');
})

it('loadSignature with isBeingOpened=true updates tabId and removes old tabId after matching', async () => {
it('loadTab with isBeingOpened=true updates tabId and removes old tabId after matching', async () => {
const sharedURL = 'https://www.google.com';
const sharedIndex = 5;
await storageSet({1: new Tab(1, sharedURL, sharedIndex, true, new Date().toISOString,
new TabSignature('Google', '🔍'))});
await loadSignature(10, sharedURL, sharedIndex, true);
await loadTab(10, sharedURL, sharedIndex, true);

// Assert:
const newStoredTabInfo = await storageGet(null);
Expand Down

0 comments on commit d400a73

Please sign in to comment.