I would like to prevent new tab creation. Either by clicking 'new tab button' either by window.open method.
Is there any way to listen on new tab creation. I don't mean 'targetcreated' event because then tab is already created. Maybe there is something similar to event.preventDefault?
Below is a very simple code that closes every new tab but I think it's very ugly and I want to improve it.
browser.on('targetcreated', (target) => {
function closeNewTabs(target) {
let targetBrowser = target.browser();
targetBrowser.pages().then(data => {
if (data.length>1) {
for (let i = 0; i < data.length; i++) {
if (i>1) data[i].close();
}
}
})
}
})
A possible workaround would be to listen to targetcreated event and then page.close
It would be something similar to
browser.on("targetcreated", async (target)=>{
const page=await target.page();
if(page) page.close();
});
It doesn't prevent creating new tabs, but it should close them immediately after opening
Related
I am trying to Differentiate Between Page Refresh, Browser Close and New tab events.
So, I want some handling on page close V/s page refresh/new tab
I came across below workaround using sessionStorage. However the issue with sessionStorage is that it gets reset or is not read even on opening link in new tab. But I want both page refresh/new tab to behave in same way V/s refresh of the page.
if (sessionStorage.getItem('reloaded') != null) {
console.log('page was reloaded');
} else {
console.log('page was not reloaded');
}
sessionStorage.setItem('reloaded', 'yes');
You'll have to use a combination of sessionStorage and localStorage to persist the data and rely on beforeunload event to handle the data removal.
The thing is beforeunload fires on both tab/window close and page refresh so we have to work around that.
localStorage will handle persistence across tabs and windows and sessionStorage will sync the data on page refresh.
const readFromStorage = (storageKey) => {
const localStorageItem = localStorage.getItem(storageKey);
const sessionStorageItem = sessionStorage.getItem(storageKey);
// You can optimize this by doing more checks but you get the idea
const itemValue = localStorageItem ?? sessionStorageItem;
if (localStorageItem !== sessionStorageItem) {
writeToStorage(storageKey, itemValue);
}
return itemValue;
};
const writeToStorage = (storageKey, value) => {
localStorage.setItem(storageKey, value);
sessionStorage.setItem(storageKey, value);
};
Event handler:
window.addEventListener('beforeunload', (e) => {
localStorage.removeItem(STORAGE_KEY);
});
Usage:
const STORAGE_KEY = '<storage_key>';
const item = readFromStorage(STORAGE_KEY);
If item is null - a tab/windows was closed. Otherwise, the data will persist across refreshes and new tabs/windows.
I have been trying for a few hours now and decided to finally post here. I have been trying so many methods to get my links to stop with preventDefault, this way I can load in content async.
All my links that i have tried that are apart of the template (like in the header) work perfectly, but any of the links brought in through an async view (and generated via js) completely skip over this snippet of code. I wanted to track anything that has a className "router" and stop the default action and run the function navigate instead.
var routeclicked = document.getElementsByClassName('router');
for(let i = 0; i < routeclicked.length; i++) {
routeclicked[i].addEventListener("click", e => {
console.log("Router is: " + routeclicked[i]);
e.preventDefault();
router = routeclicked[i].pathname;
console.log("Router 2 is: " + router);
navigate();
});
}
Attach a listener to "body" or the first non-dynamic parent.
You could go for Event.target and .closest().
Also, don't put functions inside for loops, it defies the reusability of functions.
const navigate = (EL) => {
location = EL.pathname;
}
const navigateHandler = (ev) => {
const EL = ev.target.closest(".router"); // Self or closest
if (!EL) return;
ev.preventDefault();
navigate(EL);
}
document.querySelector("body").addEventListener("click", navigateHandler);
In TestCafe, on click of an anchor tag, I have a redirect to a new page and an event that basically logs the click event to an object.
I'm wanting to test the value of the click event in the object in TestCafe, but because the redirect happens, I lose the object.
Manually I'm able to do this, as I can hold shift while clicking the link and open a new window for the redirected page, but keep the original page in the original window and then see the object in the console.
Trying to figure out if there's a way "simulate" a click, but not do the redirect. Or alternatively, be able to assert somehow immediately after the click, but before the redirect?
mini example:
await t
.click('a') // here it already redirects so I'll lose the object
.expect(object).contains('value')
The following test shows how you can disable and enable navigation for a link:
import { Selector, ClientFunction } from 'testcafe';
fixture `Navigation`
.page `example.com`;
const enableNavigationControl = ClientFunction(selector => {
const element = selector();
element.addEventListener('click', event => window.disableNavigation && event.preventDefault());
});
const disableNavigation = ClientFunction(() => window.disableNavigation = true);
const enableNavigation = ClientFunction(() => window.disableNavigation = false);
test('navigation', async t => {
const link = Selector('a');
await enableNavigationControl(link);
await disableNavigation();
await t.click(link);
// Perform assertions...
await enableNavigation();
await t.click(link);
});
i have troubles detecting a closing window after the build is done.
const newWindow = window.open(url, '_blank', options);
newWindow.onbeforeunload = () => null;
newWindow.addEventListener('beforeunload', (evt: BeforeUnloadEvent) =>
{
console.log(evt)
}
);
it works great until i do the build, there the beforeunload event does not get triggered. i also tried placing a host listener in the new window's component:
#HostListener('window:beforeunload', [ '$event' ])
beforeUnloadHander(event: BeforeUnloadEvent): void {
debugger;
}
but the same problem here. after the build is done, we don't arrive at the debugger anymore
anybody any idea what i am doing wrong? thanks for your help!
Edit Workaround
const heartBeatNewWindow = setInterval(() => {
if (newWindow.closed) {
this.canvasSettings.displayInNewWindow = false;
clearTimeout(heartBeatNewWindow);
}
}, 1500);
I had to do something similar and my approach was the following:
I created a generic catch from close event windows in the constructor of my service, them call method what handle this event. Inside this method I validate the origin of this event is the correct to execute the logic I needed. Look this example:
Inside the constructor:
if(window.addEventListener){
window.addEventListener("message", this.authService.handleMessage.bind(this), false);
}else{
(<any>window).attachEvent('onmessage', this.authService.handleMessage.bind(this));
}
And my method to handle that event:
handleMessage(event: Event) {
event.preventDefault();
const message = event as MessageEvent;
// Only trust messages from the below origin.
//
if ((message.origin !== environment.BASE_URL)) return;
const result = JSON.parse(message.data);
//Add your logic here
I Hope be helpfull.
I have popup in which I need to update the data inside it in reactively. What function or event is needed to track when a popup closes?
Currently my code structure is as follows:
let BG = browser.extension.getBackgroundPage();
let timer = BG.timer;
function updatePageTime(secondsElapsed) {
const content = document.getElementById("content");
content.innerHTML = "Current Time Spent: " + timer.getTimeElapsed();
}
document.addEventListener("DOMContentLoaded", function () {
timer.subscribe(updatePageTime);
});
document.addEventListener("unload", function () {
timer.unsubscribe(updatePageTime);
});
The problem is that unload and beforeunload do not trigger on popup closes, thus I am unable to stop updates to a non-existant DOM.
Unfortunately I did not see that unload is defined on window and not document. Simply changing the document.addEventListener("unload" to window.addEventListener("unload" fixes the problem.