After opening a new tab (second) I'm trying to switch to the first tab.
common.clickOpenNewSession(); //it opens the new tab
browser.getAllWindowHandles().then(function (handles) {
var secondWindowHandle = handles[1];
var firstWindowHandle = handles[0];
browser.switchTo().window(secondWindowHandle).then(function () { //the focus moves on new tab
browser.sleep(3000);
expect(browser.driver.getCurrentUrl()).toContain("url");
//do some actions
});
//below it doesn't work. I try to go back on previous tab without closing the second tab
browser.actions().sendKeys(protractor.Key.CONTROL).sendKeys(protractor.Key.TAB).perform();
browser.sleep(4000);
browser.driver.switchTo().window(firstWindowHandle);
browser.setLocation('http://google.com');
});
The problem is that you're trying to go to the previous tab by using ctrl + tab, instead of using the window handles to switch back. This is not supported in WebDriver, because using ctrl + tab is a system operation, and can't be emulated on your browser for all OS/browsers. Just use browser.switchTo() again.
#Aaron This code get all the browser handles available and resolves the promise. Then opens the tab created by a <a href='newlink' target='_blank'>Link</a>:
POFile.buttonWithABlankTarget.click().then(function() {
browser.getAllWindowHandles().then(function(handles) {
var newTabHandle = handles[1];
browser.switchTo().window(newTabHandle).then(function () {
// Expect the newly opened tab URL to equal the href of the invitation
expect(browser.driver.getCurrentUrl()).toContain("http://...");
});
});
});
In the same fashion, you could switch between tabs:
it("should open the first tab", function() {
browser.getAllWindowHandles().then(function (handles) {
browser.switchTo().window(handles[0]);
});
});
And, of course, close a tab:
it("should close the second tab and return to the first tab", function() {
browser.getAllWindowHandles().then(function (handles) {
// We currently are on the second tab...
browser.driver.close();
browser.switchTo().window(handles[0]);
});
});
Hope this helps!
Related
I have a custom popup functionality. What I want is for the browser back button to close this popup.
My ideal scenario would be to NOT show a hashtag in the URL bar.
I have tried putting window.history.pushState('forward', null, ''); in my showPopup() function and then doing the following:
$(window).on('popstate', function () {
closePopup();
});
This does work but the problem is when I manually close the popup I have to press the back button twice to navigate back to the previous page (obviously because a browser history entry was added when the popup was opened).
What is the best way of doing this? Can it be done without adding a browser history entry? Essentially what I am trying to do is replicate the behaviour of a mobile app. Press the back button in a mobile app will usually dismiss any open modals or context menus.
$('.popup-link').click(function() {
showPopup();
});
$('.popup-close').click(function() {
hidePopup();
});
function showPopup() {
$('.popup').addClass('active');
}
function hidePopup() {
$('.popup').removeClass('active');
}
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>
It is not possible to do it without adding browser history entries since you cannot override the back button behaviour, see Intercepting call to the back button in my AJAX application: I don't want it to do anything
Sujumayas answer is a good option, you should introduce some additional variable though to avoid problems with the history when opening multiple popups (e.g. when clicking the button multiple times)
Here is some possible sample code:
let popupOpen = false;
$(".popup-link").click(function() {
showPopup();
});
$(".popup-close").click(function() {
window.history.back();
});
function showPopup() {
if (popupOpen) {
window.history.back();
}
popupOpen = true;
window.history.pushState("forward", null, "");
$(".popup").addClass("active");
}
function hidePopup() {
popupOpen = false;
$(".popup").removeClass("active");
}
$(window).on("popstate", function() {
hidePopup();
});
Additionally please note that you might have problems with Opera Mini: https://caniuse.com/#search=history
Altho I don't recommend to override regular browser history managment (back button) to use it as you please....
I think that the only thing you missed in your example is that the close button should not close the modal by itself, but instead just execute a backbutton event (which will eventually close the modal).
That simple fix and it will work as you wanted.
I am doing already something like this, and it works nicely with the browser back-button and by pushing the android back-button as well. I am also not showing a hashtag in the URL bar.
Here is the stub (I just tried to apply that to Your scenario):
function freezeHistory() {
window.history.pushState({}, window.document.title, window.location.href);
}
function goBack() {
/*
Custom history back actions: close panel, close popup, close drop-down menu
*/
var popupOpen = $(".popup.active").length > 0;
if(popupOpen) {
hidePopup();
return false;
}
window.history.back();
return true;
}
function showPopup() {
$('.popup').addClass('active');
freezeHistory();
}
function hidePopup() {
$('.popup').removeClass('active');
}
$(window).on("popstate", function(e) {
/*
Browsers tend to handle the popstate event differently on page load.
Chrome (prior to v34) and Safari always emit a popstate event on page load,
but Firefox doesn’t.
*/
goBack();
})
If this won't work for You out-of-the box, it is because IMHO You may need to clarify a little bit how do You expect to manage the page history. Feel free to add more detail to Your question if this isn't working as You'd expect now, but anyway, I strongly believe You got the idea and You are able to apply it inside the scenario of Your web-app.
Open popup and try going back and forth with the browser history buttons
$(document).ready(function () {
// manage popup state
var poped = false;
$('.popup-link').click(function () {
// prevent unwanted state changtes
if(!poped){
showPopup();
}
});
$('.popup-close').click(function () {
// prevent unwanted state changtes
if(poped){
hidePopup();
}
});
function showPopup() {
poped = true;
$('.popup').addClass('active');
// push a new state. Also note that this does not trigger onpopstate
window.history.pushState({'poped': poped}, null, '');
}
function hidePopup() {
poped = false;
// go back to previous state. Also note that this does not trigger onpopstate
history.back();
$('.popup').removeClass('active');
}
});
// triggers when browser history is changed via browser
window.onpopstate = function(event) {
// show/hide popup based on poped state
if(event.state && event.state.poped){
$('.popup').addClass('active');
} else {
$('.popup').removeClass('active');
}
};
.popup {
background-color: #ccc;
width: 300px;
height: 300px;
display: none;
}
.popup.active {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="popup-link">Click</button>
<div class="popup">
<button class="popup-close">x</button>
<!-- popup content here -->
</div>
You could add window.history.go(-2) to your popstate. That should take you back twice, which would be your original page before the modal as pushState added an entry to your history object.
Conversely, you could use history.back(2)
Use window.location.href to go 2 pages back and reload
Just run window.history.back(); when closing the popup.
$('.popup-close').click(function() {
hidePopup();
window.history.back();
});
You would have two options to implement this:
Option 1: Using the window.beforeunload event. reference
$('.popup-link').click(function() {
showPopup();
$(window).on("beforeunload", hidePopup);
});
$('.popup-close').click(hidePopup);
function hidePopup() {
$(window).off("beforeunload", hidePopup);
$('.popup').removeClass('active');
}
Demo
Option 2: Using the HTML5 History API. reference
$('.popup-link').click(function() {
showPopup();
window.history.pushState('popup-open', null, '');
$(window).on('popstate', hidePopup);
});
$('.popup-close').click(function() {
if(history.state == 'popup-open') {
window.history.back();
}
hidePopup();
});
function hidePopup() {
$(window).off('popstate', hidePopup);
$('.popup').removeClass('active');
}
Demo
Edit: sujumayas's idea is also pretty good one.
Demo
Further, I'ld recommend to register the popstate / beforeunload events only when necessary and unregister them, when you no longer need 'em in order to avoid overhead.
if anyone use bootstrap with any version you can use this
let popupOpen = false;
//show
$(".popup-link").on('click',(function() {
showPopup();
})
);
// hide
$(".popup-close").on('click',(function() {
window.history.back();
})
);
// on click back button
$(window).on("popstate", function() {
if (popupOpen) {
hidePopup();
}
});
// for bootstrap, if clicked outside the modal or close somehow
$(window).on('hidden.bs.modal', function(e) {
// Make sure is open and the same modal
if (e.target.id=='exampleModal' && popupOpen) {
popupOpen = false;
window.history.back();
}
});
function showPopup() {
// if open back
if (popupOpen) {
window.history.back();
}
popupOpen = true;
// push the browser history
window.history.pushState("forward", null, "#popup");
// you have to use the id
$("#exampleModal").modal('show');
}
function hidePopup() {
popupOpen = false
// you have to use the id to close the modal
$("#exampleModal").modal('hide');
}
How can I execute this function only once and when the browser tab/window is active ?
$(function(){
noty({text:'Here is my text',type:'error'});
return false;
});
If I use:
$(window).one('focus', function(){
The function is executed but only if I leave the tab and come back again.
Any ideas ?
Many thanks
If you use the load event it will fire when the page is loaded.
$(document).ready(() => {
$(window).on('load', () => {
noty({ text: 'Here is my text', type: 'error' });
});
});
What do you mean by 'is active' ?
If you need this function to be called just one time after load, you can use load event or ready with jquery.
If it's every time the tab is active, so when your user is on the tab, and the mouse focus your document, you can use the focus event.
let activated = false;
window.addEventListener('focus', function() {
if(!activated) {
console.log('test');
activated = true;
}
})
i am with stuck an unorthodox requirement, i have opened a window on page load using jquery like this
$(document).ready(function() {
loadLifeCare();
});
and the function goes like this
function loadLifeCare()
{
window.open('/abc/abc/abc','','width=100,height=100');
}
now this function loads a url in the new window which creates a session for the user on different
domain.
i just need to know if it is either possible to close this window after few seconds or change the href and reload it to a different link,
and i can't code on the child window.
This will open the window and then close it after 10 seconds...
function loadLifeCare()
{
var wnd = window.open('/abc/abc/abc','','width=100,height=100');
setTimeout(function() {
wnd.close();
}, 10000);
}
If you want to redirect it elsewhere, you can do this...
function loadLifeCare()
{
var wnd = window.open('/abc/abc/abc','','width=100,height=100');
setTimeout(function() {
wnd.location.href = "http://wherever.com";
}, 10000);
}
I am working on a Chrome extension, but for some reason I am able to create a new tab only in a single function and not in multiple functions.
Code-
function editorial() {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
var tab_url=tabs[0].url;
var new_url=tab_url.slice(11);
chrome.tabs.create({ url:"http://www.discuss." + new_url});
});
}
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('viewEditorial');
if (btn) {
btn.addEventListener('click', editorial);
}
});
function friends()
{
var frnd_name=document.getElementById('frnd1').value;
alert(frnd_name+"rocks");
/*chrome.tabs.query({currentWindow: true, active: true}, function(tabs){
var tab_url=tabs[0].url;
var new_url=tab_url.slice(11);
chrome.tabs.create({ url:"http://www.discuss." + new_url});*/
}
document.addEventListener('DOMContentLoaded', function () {
var btn2 = document.getElementById('viewFriends');
if (btn2) {
btn2.addEventListener('click', friends);
}
});
I want to be able to use the frnd_name to open a url in a new tab in the function friends().
If the commented part is not used then it is working fine and the alert message is also coming but if the commented part is used then for some reason, it does not work.
Any ideas as to what the bug/problem is?
I think it's because chrome.tabs cannot be used in content scripts.
You should do this instead:
Send a message to your background page using chrome.runtime.sendMessage
In your background page, use chrome.runtime.onMessage to catch the message
Finally use chrome.tabs.create to create a new tab.
Hope this helps
Well, the problem was due to a missing '}' that was not there.
I wasted a lot of time over this and ultimately the bug was such a simple one.
Now, I have learnt a lesson, always check ur code twice for proper braces.
I have two windows , the second is a popup , and I want to trigger an event from the parent (the first one where I have a link to this popup).
here's a javascript code for the trigger (in the parent window's javascript code):
winPop=window.open(opts.url,opts.nom,"width="+opts.width+",height="+opts.height+",top="+opts.top+",left="+opts.left);
winPop.onload=function(){
$(winPop.document).trigger('connected', {
jid: "jid",
password: '123'
});
}
This javascript code launchs the popup and tries to trigger an event bound in popup (ready) function:
$(document).ready(function () {
$(document).bind('connected', function () {
alert("Hello , I'm here");
});
The problem is that using the previous javascript code .. the bound event is not triggered as predicted.
Thanks in advance
I had done this earlier with something like this:
var realWindowOpen = window.open;
window.open = wrappedWindowOpen;
function wrappedWindowOpen(url, name, specs, replace) {
window.open = realWindowOpen;
var windowHandle = window.open(url, name, specs, replace);
if (windowHandle)
console.log("New Popup Window created: ", {name:name});
else
console.error("New Window Failed. " + {name:name});
if (popupFnCreationNotify) {
popupFnCreationNotify(windowHandle);
popupFnCreationNotify = null;
}
window.open = wrappedWindowOpen;
}
// Calling example
var popupFnCreationNotify = function() {
console.log("I got called back");
};
window.open("my url");
Please note:
realWindowOpen always points to window.open.
I wrap the actual window.open with wrappedWindowOpen as you can see in the code.
Before calling window.open, the caller sets the popupFnCreationNotify to any callback function they wish.