How to close a chrome browser tab via terminal? - bash

Currently I am writing a script that invokes a new instance of the chrome browser.
I know how to call chrome to open a *.html document in a new tab.
google-chrome *.html
Chrome will open a new tab to show that file.
How can I close the tab in terminal without closing other tabs or closing the browser window?

only linux answer:
Perhaps wmctrl could be of some assistance. You could use the -c option that closes a window gracefully:
wmctrl -c "tab title"
The string chrome is matched against the window titles. Note that the window might not close if some message pops-up (e.g. when you have multiple tabs open).

You can look into chrome remote debugging:
chromium --remote-debugging-port=9222
and connect to it with some kind of client ( https://github.com/cyrus-and/chrome-remote-interface seems good). The debug protocol is used for a number of applications, but with some work you can achieve the kind of functionality you want. Here are some docs for you to check out: https://chromedevtools.github.io/devtools-protocol/tot/Page
Or perhaps chromix-too, which is based on an extension, daemon and client architecture.
https://github.com/smblott-github/chromix-too
This seems to be much easier to use, and might be exactly what you want, though the extension is a bit inconvenient, and there seems to be demand for more capabilities to be supported.
EDIT The query you would be looking for is:
const chrome = require('ox-chrome-remote-interface');
chrome.List().then(tabs=>{
const list = tabs
.filter(t=>t.type == 'page' && t.title.includes(TITLE))
.map(t => t.id)
if(list.length==1){
chrome.Close({id:list[0]})
} else {
console.error(`${list.length} tabs match.`)
}
})

Related

How can I target a new popup window, rather than a tab using Selenium?

For the moment I have been using the following to essentially check that a new tab has opened, and then switch to that tab:
#wait.until{#driver.window_handles.length > 1}
#driver.switch_to.window(#driver.window_handles[1]) where 1 is the tab number
I wanted to know how to use something similar like the above, but for windows where this window is an iFrame, using Webdriver.
I need to supply some details in an iframe, and then switch back to the main window (although once the details are submitted the iframe will close and I should be redirected back to the main window I had earlier so this should be automatic I think)
To be clear also, I am using the Ruby binding of Selenium.
If you need to locate something inside an iframe, before you have to switch to the interested iframe. For example, in Java, if you can identify the iframe by id:
driver.switchTo().frame(driver.findElement(By.id("idframe")));
Finally, to return back:
driver.switchTo().defaultContent();
I never used ruby but, from here should be:
# switch to a frame
driver.switch_to.frame "some-frame" # id
and
# switch back to the main document
driver.switch_to.default_content

What can I do with Firefox's Browser Console which I can't with Web Console?

I have recently known that Firefox has a Browser Console (different than Web Console) which can be enabled setting devtools.chrome.enabled to true.
I have searched information about what can I do with it, but I have only found
The Browser Console lets you see all JavaScript errors and logging in
the browser, including from Firefox code. To enable it, go to
about:config in the url bar and set devtools.chrome.enabled to true.
Activate it through with the menu Web Developer > Browser Console.
(https://developer.mozilla.org/en-US/docs/Debugging_JavaScript#Browser_Console)
I have discovered that Browser console is useful because I can see the errors in sandboxed GreaseMonkey scripts. But I guess it can do lots of interesting things, where can I find some info?
This MDN page says it all (when I asked this question that page didn't exist, it was created the Aug 7, 2013 5:04:27 PM)
Browser Console
The Browser Console is like the Web Console, but applied to the whole
browser rather than a single content tab.
So it logs the same sorts of information as the Web Console - network
requests, JavaScript, CSS, and security errors and warnings, and
messages explicitly logged by JavaScript code. However, rather than
logging this information for a single content tab, it logs information
for all content tabs, for add-ons, and for the browser's own code.
Similarly, you can execute JavaScript expressions using the Browser
Console. But while the Web Console executes code in the page window
scope, the Browser Console executes them in the scope of the browser's
chrome window. This means you can interact with all the browser's tabs
using the gBrowser global, and even with the XUL used to specify the
browser's user interface.
To open the Browser Console, select "Browser Console" from the Web
Developer submenu in the Firefox Menu (or Tools menu if you display
the menu bar or are on Mac OS X):
You can see that the Browser Console looks and behaves very much like
the Web Console:
most of the window is occupied by a pane that display messages
at the top, a toolbar enables you to filter the messages that appear
at the bottom, a command line interpreter enables you to evaluate JavaScript expressions.
Browser Console logging
The Browser console logs the same sorts of messages as the Web
Console:
HTTP requests
Warnings and errors (including JavaScript, CSS, security warnings and errors, and messages explicitly logged by JavaScript code using
the console API)
Input/output messages: commands send to the browser via the command line, and the result of executing them.
However, it displays such messages from:
web content hosted by all browser tabs
the browser's own code
add-ons.
Messages from add-ons
The Browser Console displays messages
logged by all Firefox add-ons.
For example, here's a very simple Add-on SDK add-on that just
logs an error when the user clicks an icon:
// base-64 encoded icon, from http://edmerritt.com/'s "Vaga" icon set
var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9" +
"hAAAC90lEQVR4Xk1STUgbWxQ+mbmZNGqcJGjaGBq7UUGpYCEUXMSFLgRBdKeIG6F06aKUt6irEks" +
"R3JjWGAquSjeW8p6g3UQeCPKeJvCgRYP4QxK0TaPPGJPMZMzM3J4bM9ED35x7z/nOud+9c0yKooBh" +
"h6FQV1lRZmRZ9l8riksplQjhedVssWQQm4SQwOMXL3YNviAIwBmb/WDwVT6X+1snZMz18GFLe3s7e" +
"dLdDR2dncTl9bZQjhvD/D//zc+/gTtGjGJJkv5wtrTYHLIMaioFFL2sqgA8D3VWK9gcDjhvbLRlUq" +
"mX38LhB93Pn08BGnewuNhVyOennW63zX5xAdfJJKiXl6Di1ewTExWvZrNQwriYz4PT4yH/Hx9PHm5" +
"s3DRQ8M5CQ0OzXZKgnMmAjqfqmBBHRqC+pwcco6OgUQoaxhXMO3QdiMVCsvH462Qy2UxKkuTHO4N2" +
"clIh6UimABVA1bOYztaYB1TpvH8fThMJj1vTholcLLqsHAeqJN0Wo9dwz0wtFkFjC6MRxus9Hrj68" +
"QM0TRsgiiQRARtI2J0yQpVYzuVuGqA3VFCGchnqzGaQrq5A13Uf4fE/lzSNUJ4HDZMGObu1xXArv6" +
"rOhDy5VALzvXtMQSvHC0Imz4YJA4ysVQvE3l7oCAaZZ/EaTPhLc4UC1DU1sQZJTsAJO0+ngXM6Qef" +
"5mgKusRGY8aJYK2YqCfLSiQSIbW3sClGOx/EsZLP5M10Hs8sFOsdVyL/W1yERCkF6ba1WLGD+Fz6q" +
"xObh6VOmIML5ZmZ26x2Odz+PjtRzfBzB6wXebgeTIEBubw/AYgEz7q2PHsE5HnK6vw/uvj7gRPEvV" +
"LAKOEgVbL59u/zl2bPy2vQ03Z6bo7vBID0Ih+n3hQW6NTtLMUc/jo/TjaUlGovFtqPRaD97WFZcQ2" +
"xlZSoSCJx8RvLy0BB97/fTD4OD9NPkJP0aCNB/IxGKhX/u7Oz0Mz5rYGKfuxaPx5tR2jBiAHM+9K2" +
"IJK6jiAhi1efznRn837fI5BVWw7NCAAAAAElFTkSuQmCC";
widget = require("sdk/widget").Widget({
id: "an-error-happened",
label: "Error!",
contentURL: icon,
onClick: logError
});
function logError() {
console.error("something went wrong!");
}
If you build this as an XPI file, then open the Browser Console,
then open the XPI file in Firefox and install it, you'll see an icon
in the Add-on bar:
Click the icon. You'll see output like this in the Browser Console:
For Add-on SDK-based add-ons only, the message is prefixed with the
name of the add-on ("log-error"), making it easy to find all messages
from this add-on using the "Filter output" search box. By
default, only error messages are logged to the console, although you
can change this in the browser's preferences.
Browser Console command line
Like the Web Console, the command line interpreter enables you to
evaluate JavaScript expressions in real time:
Also like the Web Console's command line interpreter, this command
line supports autocomplete, history, and various keyboard shortcuts
and helper commands. If the result of a command is an object, you can click on the object to see its details.
But while the Web Console executes code in the scope of the content
window it's attached to, the browser console executes code in the
scope of the chrome window of the browser. You can confirm this by
evaluating window:
This means you can control the browser: opening, closing tabs and
windows and changing the content that they host, and modify the
browser's UI by creating, changing and removing XUL elements.
Controlling the browser
The command line interpreter gets access to the tabbrowser object,
through the gBrowser global, and that enables you to control the
browser through the command line. Try running this code in the Browser
Console's command line (remember that to send multiple lines to the
Browser Console, use Shift+Enter):
var newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("load", function() {
newTabBrowser.contentDocument.body.innerHTML = "<h1>this page has been eaten</h1>";
}, true);
newTabBrowser.contentDocument.location.href = "https://mozilla.org/";
It adds a listener to the currently selected tab's load event that
will eat the new page, then loads a new page.
Modifying the browser UI
Since the global window object is the browser's chrome window, you can
also modify the browser's user interface. On Windows, the following
code will add a new item to the browser's main menu:
var parent = window.document.getElementById("appmenuPrimaryPane");
var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
makeTheTea.setAttribute("label", "A nice cup of tea?");
parent.appendChild(makeTheTea);
On OS X, this similar code will add a new item to the "Tools" menu:
var parent = window.document.getElementById("menu_ToolsPopup");
var makeTheTea = gBrowser.ownerDocument.defaultView.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
makeTheTea.setAttribute("label", "A nice cup of tea?");
parent.appendChild(makeTheTea);

How to extract number of currently opened tabs?

I want to automatically count number of tabs that are open in Firefox so I can track this over time. It is not enough to get an add-on that displays current number in the browser.
From .sqlite tables Firefox saves for each profile I have not been able to decipher any table of currently opened tabs. I also looked for a column in the history table that tells whether page is currently open or not. Is this information available in the databases at all? If so, where is it stored? If not, how do add-ons like Tab Counter find this number?
Open the about:telemetry link in Firefox and click scalars tab from the sidebar menu. Alternatively, opening about:telemetry#scalars-tab_search=tab will take you directly to the scalars tab.
The browser.engagement.max_concurrent_tab_count key will show the number of tabs active for the session, but does not update when a tab is closed. Instead, if you want to update this value you will need to restart your browser.
The browser.engagement.tab_open_event_count key shows the current number of open tabs at a given time and is updated dynamically.
Online
Within a running Firefox session, it's easy to extract the data using the Mozilla Add-on API. I wrote a simple Tab Count Logger extension that does this, and saves the count to an SQLite database.
The relevant part of the code is:
const tabs = require("sdk/tabs");
const windows = require("sdk/windows").browserWindows;
console.log("Windows: " + windows.length + "; tabs: " + tabs.length);
Offline
Opened tabs are stored in sessionstore.js in the profile directory, not in SQLite. This file is JSON. A script to count tabs:
#!/usr/bin/env python3
# Count open tabs from a firefox profile
# Working directory is the root of a Firefox profile.
import json
j = json.loads(open("sessionstore.js", 'rb').read().decode('utf-8'))
def info_for_tab(tab):
try:
return (tab['entries'][0]['url'], tab['entries'][0]['title'])
except IndexError:
return None
except KeyError:
return None
def tabs_from_windows(window):
return list(map(info_for_tab, window['tabs']))
all_tabs = list(map(tabs_from_windows, j['windows']))
print('Statistics: {wins} windows, {tabs} total tabs'.format(wins=len(all_tabs), tabs=sum(map(len, all_tabs))))
After having saved this to ~/bin/firefox_count_tabs, you can get the information for all your profiles as in:
for i in ~/.mozilla/firefox/*.*; do test -d $i && (echo "== $i =="; cd $i; ~/bin/firefox_count_tabs ); done
The count will be shown on the exit confirm dialog - if you hadn't disable that 😂️
update 2022-11-02: only when you have only one window
#Xidus: History and bookmarks are stored in the places.sqlite. You cannot determine tabs and windows information here.tabs and windows information are stored in the sessionstore.js file.You can refer this links:
http://kb.mozillazine.org/sessionstore.js
http://forums.mozillazine.org/viewtopic.php?f=38&t=622036&start=60&p=12098147#p12098147
You can count tabs in the Browser Console (not Web Console) with:
gBrowser.tabs.length
The Browser Console is disabled by default. To enable it you can either:
Tick the option "Enable browser chrome and add-on debugging toolboxes" in the Web Developer Tools settings.
Go to about:config and search for devtools.chrome.enabled, and toggle it to true.
After that look for Browser Console in the More tools menu, or open the Developer Console with [CTRL]+[SHIFT]+J, and you can now enter the above.
option-1
option-2
[CTRL]+[SHIFT]+J

How would one display a prompt after installation of an extension?

When my add-on installs it needs to prompt the user to get a username or something like that. After that it stores it and shouldn't ask again. Where would I place this prompt? install.rdf? browser.xul?
There is no explicit mechanism to run code when the extension installs - you should simply do it when your extension runs for the first time. The easiest approach would be checking whether the user name is already set up. If it is not - show the prompt.
It is not recommended to show a modal dialog, those are extremely annoying to users, especially when they suddenly appear during Firefox start-up. You should instead open your page in a tab. A slight complication: Firefox might be restoring a previous session when it starts up. If you open your page too early the session restore mechanism might replace it. So you should wait for the sessionstore-windows-restored notification, something like this should work:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
var observer = {
observe: function(subject, topic, data)
{
Services.obs.removeObserver("sessionstore-windows-restored", this);
var browser = window.getBrowser();
browser.loadOneTab("chrome://...", {inBackground: false});
},
QueryInterface: XPCOMUtils.generateQI([
Components.interfaces.nsIObserver,
Components.interfaces.nsISupportsWeakReference
])
};
Services.obs.addObserver("sessionstore-windows-restored", observer, true);
A final complication is that your code is probably running from a browser window overlay - meaning that there will be multiple instances of your code if the session restored contains more than one window. You probably want the code above to run only once however rather than opening your first-run page in every browser window. So you will have to coordinate somehow, maybe via preferences. A slightly more complicated but better solution would be having a JavaScript code module in your extension - code modules are only loaded once so you wouldn't have a coordination issue there.
Try using an addonlistener https://developer.mozilla.org/en/Addons/Add-on_Manager/AddonListener#onInstalling%28%29
Or by using the preferences: https://stackoverflow.com/a/958944/1360985

Firefox browser disable safe mode

I am using Windows 7 and I've been playing with the Firefox browser for a while.
I want to create a kiosk app using it, I installed a plugin for that, but the problem is that when I start the Firefox app, if I press Shift, it enters safe mode.
I read some guides on Google that tell me to edit chrome/browser.jar but I have no such file in my Firefox folder.
I need some help for disabling the feature that lets me enter safe mode by pressing Shift.
You cannot really disable safe mode by editing text files, the handling of the Shift key is inside compiled code. You can however disable the dialog that pops up by removing this code from components/nsBrowserGlue.js:
// check if we're in safe mode
if (Services.appinfo.inSafeMode) {
Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul",
"_blank", "chrome,centerscreen,modal,resizable=no", null);
}
You can also leave extensions enabled in safe mode. For that you will have to also edit modules/XPIProvider.jsm and remove all occurrences of code like:
if (Services.appinfo.inSafeMode)
return false;
Both files can be found inside the onmi.ja archive in the Firefox directory.
That said, the proper solution to this problem would be running your own application on top of XULRunner which would allow you to design your own user interface for kiosk mode. Sadly, Open Kiosk (which is probably what you are using) is ancient and predates XULRunner.
I managed to disable Firefox session restore and safe mode tweaking these two preferences:
browser.sessionstore.resume_from_crash => false
toolkit.startup.max_resumed_crashes => -1

Resources