Start Firefox and wait until it is closed

Question

I want to start the Firefox web browser as a process to visit a specific website and then wait until it is closed.

A special situation is that the browser may already be open and running because the user may have already visited some website.

In this case, the browser will likely open a new tab in the existing window and the recently launched process will be terminated immediately. This should not confuse my wait process: either I want a new browser window (if this can be brought into action in some way, perhaps via command line arguments) and wait until it is closed, or save the existing browser window and wait. until all tabs resulting from my process are closed.

Environment

I think it doesn't matter, but my programming environment Java

and you can assume that I know the path to the browser.

Example

The only browser I can get the expected behavior for is Internet Explorer (sigh). Here I need to create a new batch version of the script in a temporary folder with something like

start /WAIT "" "C:\Program Files\Internet Explorer\iexplore.exe" -noframemerging http://www.test.com/

      

Then I run the batch script instead of the direct browser and delete it as soon as I am done waiting.

Intended process

To make the required process clearer:

  • My program will start.
  • My program starts the Firefox browser as a separate process and provides the visit URL as an argument to that process.
  • The Firefox browser runs asynchronously like a new process and visits the provided URL. It's easy so far.
  • After starting a new process (Firefox browser), my own program should wait for the specified process to finish. This is the hard part because
    • Many modern browsers run multiple processes. I will need to wait for them all.
    • Many modern browsers can somehow "detach" from the process I was running. Sorry, I don't know a better word, I mean: I start a process, which then starts another process and terminates immediately while the other process continues to run. If I expect the browser process originally started by my program, the wait will complete while the browser is still open.
    • A special case of the above is the tabbed browsing implemented in many browsers: if the browser is already open (in a separate process started by the user) when it starts, my newly launched browser can simply pass the URL to visit the existing process and terminate. The user is still at my provided URL while my program thinks it has closed the browser. This problem can be prevented by specifying a special command line argument, for example noframemerging

      for IE.
  • Once the browser exits, or all the tabs associated with the URL I specified have been closed, my program will stop waiting and continue its activity instead.

The use case is that I have a web application that can run locally or on a server. If it runs locally, it starts a web server and then opens a browser to visit the login page. When the browser is closed, this web application must also be disabled. This is safe for Internet Explorer, for all other cases the user must close the browser and then, obviously, the web application. Thus, if I could reliably wait for Firefox to finish, it would greatly improve the user experience.

Solution preferences:

The solutions are preferred in the following order

  • Everything comes with a pure Java JRE. This includes browser-specific command line arguments.
  • Things that require me to, for example, create a batch script (like in the case of IE.)
  • Anything that requires third party open source libraries.
  • Anything that requires a 3rd party closed source library.

Any platform independent answer (working on both Windows and Linux) is preferred over platform specific.

Cause. Ideally, I would like to know what exactly is being done and include it in my own code. Since I want to support different browsers (see "PS" below), I would like to not include one library per browser. Finally, I cannot use commercial or proprietary libraries, but unless a better answer comes up, I will of course mark any working solution with accept. I'll accept the first (reasonably good) working answer like "1". If lower preference answers come up, I will wait a few days before accepting the better one.

PS

I ran a couple of similar questions for other browsers. Since I believe browsers are very different in the command line arguments they digest, like startup threads and subprocesses, I think this makes sense.

+3


source to share


1 answer


Here's a sample program that can somehow demonstrate the ability of the selenium library to do what you want. Before running this program, you need to download the selenium library and install it in your IDE.

The program allows you to click on a button. Then Firefox browser automatically opens and launches the website after a few seconds. Wait for the site to load. After that, you can close the Firefox browser. The program also closes automatically after 2 seconds.



import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.net.ConnectException;
import javax.swing.*;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class AnotherTest extends JFrame {

    WebDriver driver;
    JLabel label;

    public AnotherTest() {
        super("Test");
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width - 400) / 2, (screenSize.height - 100) / 2, 400, 100);
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        addWindowListener(new java.awt.event.WindowAdapter() {

            public void windowClosing(java.awt.event.WindowEvent evt) {
                quitApplication();
            }
        });

        JButton jButton1 = new javax.swing.JButton();

        label = new JLabel("");
        JPanel panel = new JPanel(new FlowLayout());
        panel.add(jButton1);

        add(panel, BorderLayout.CENTER);
        add(label, BorderLayout.SOUTH);


        jButton1.setText("Open Microsoft");

        jButton1.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {

                label.setText("Loading browser. Please wait..");

                java.util.Timer t = new java.util.Timer();
                t.schedule(new java.util.TimerTask() {

                    @Override
                    public void run() {
                        openBrowserAndWait();
                    }
                }, 10);
            }
        });

    }

    private void openBrowserAndWait() {
        driver = new FirefoxDriver();
        String baseUrl = "https://www.microsoft.com";
        driver.get(baseUrl);

        java.util.Timer monitorTimer = new java.util.Timer();
        monitorTimer.schedule(new java.util.TimerTask() {

            @Override
            public void run() {
                while (true) {
                    checkDriver();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }, 10);
    }

    private void checkDriver() {
        if (driver == null) {
            return;
        }

        boolean shouldExit = false;

        try {
            label.setText(driver.getTitle());
        } catch (NoSuchWindowException e) {
            System.out.println("Browser has been closed. Exiting Program");
            shouldExit = true;
        } catch (Exception e) {
            System.out.println("Browser has been closed. Exiting Program");
            shouldExit = true;
        }

        if (shouldExit) {
            this.quitApplication();
        }
    }

    private void quitApplication() {
        // attempt to close gracefully
        if (driver != null) {
            try {
                driver.quit();
            } catch (Exception e) {
            }
        }

        System.exit(0);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new AnotherTest().setVisible(true);
            }
        });
    }
}

      

Selenium is mainly used for web application automation testing. It can open browsers directly and read the html content in it. For more information see http://www.seleniumhq.org/ .

+2


source







All Articles