java firefox browser process wait

java - Inicie Firefox y espere hasta que esté cerrado



browser process (1)

Pregunta

Quiero iniciar el navegador web Firefox como proceso para visitar un sitio web específico, luego esperar hasta que se cierre.

Una situación especial es que el navegador ya puede estar abierto y ejecutándose, ya que el usuario puede haber visitado algún sitio web.

En ese caso, el navegador probablemente abrirá una nueva pestaña en una ventana existente y el proceso recién iniciado se finalizará de inmediato. Esto no debería confundir mi proceso de espera: o bien, quiero una nueva ventana del navegador (si eso se puede aplicar de alguna manera, tal vez a través de argumentos de línea de comando) y esperar hasta que se cierre, o mantener la ventana del navegador existente y esperar hasta que aparezcan todas las pestañas de mi proceso están cerrados.

Ambiente

Creo que no importa, pero mi entorno de programación es Java y puedes suponer que conozco la ruta del navegador.

Ejemplo

El único navegador para el que puedo obtener el comportamiento esperado es Internet Explorer (suspiro). Aquí, básicamente necesito crear un nuevo script por lotes en una carpeta temporal con algo como

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

Luego ejecuto el script por lotes en lugar de directamente el navegador y lo elimino una vez que termine de esperar.

Proceso previsto

Para aclarar el proceso previsto:

  1. Mi programa comienza
  2. Mi programa inicia el navegador Firefox como un proceso separado y proporciona una URL para visitar como argumento para ese proceso.
  3. El navegador Firefox se ejecuta de forma asíncrona, como un nuevo proceso, y visita la URL proporcionada. Hasta ahora, esto es fácil.
  4. Después de iniciar el nuevo proceso (el navegador Firefox), mi propio programa debería esperar a que dicho proceso finalice. Esta es la parte difícil, ya que
    1. Muchos navegadores modernos inician múltiples procesos. Tendría que esperar a todos ellos.
    2. Muchos navegadores modernos pueden de alguna manera "separarse" del proceso que inicié. Lo siento, no sé una palabra mejor, lo que quiero decir es: inicio un proceso que luego inicia otro proceso y finaliza inmediatamente mientras el otro proceso sigue ejecutándose. Si espero el proceso del navegador iniciado originalmente por mi programa, la espera finalizará mientras el navegador aún esté abierto.
    3. Un caso especial de lo anterior es la navegación con pestañas como se realiza en muchos navegadores: si el navegador ya está abierto (en un proceso separado iniciado por el usuario) cuando lo ejecuto, mi proceso de navegador recién iniciado puede comunicar simplemente la URL para visitar el proceso existente y finalizar. El usuario todavía está en mi URL proporcionada mientras mi programa cree que ha cerrado el navegador. Este problema puede ser prohibido especificando un argumento especial de línea de comando, como noframemerging para el IE.
  5. Una vez que el navegador ha finalizado o se han cerrado todas las pestañas relacionadas con la URL que proporciono, mi programa dejará de esperar y, en su lugar, continuará haciendo sus negocios.

El caso de uso es que tengo una aplicación web que puede ejecutarse localmente o en un servidor. Si se ejecuta localmente, inicia un servidor web, luego abre el navegador para visitar la página de entrada. Una vez que se cierra el navegador, esa aplicación web también debería cerrarse. Esto funciona de manera confiable para Internet Explorer, para todos los demás casos, el usuario debe cerrar el navegador y luego, explícitamente, la aplicación web. Por lo tanto, si pudiera esperar de manera confiable a que Firefox terminara, esto haría que la experiencia del usuario fuera mucho mejor.

Preferencias de solución:

Las soluciones se prefieren en el siguiente orden

  1. Cualquier cosa que se envíe con Java JRE puro. Esto incluye argumentos especiales de línea de comandos para el navegador.
  2. Cosas que me requieren, por ejemplo, crear un script por lotes (como en el caso de IE).
  3. Cualquier cosa que requiera bibliotecas de código abierto de terceros.
  4. Cualquier cosa que requiera bibliotecas de código cerrado de terceros.

Cualquier respuesta independiente de la plataforma (que funcione tanto en Windows como en Linux) es preferible a las que dependen de la plataforma.

Motivo: en el caso ideal, me gustaría saber qué se hace exactamente e incluirlo en mi propio código. Como quiero admitir diferentes navegadores (ver "PS" a continuación), me gustaría evitar tener que incluir una biblioteca por navegador. Finalmente, no puedo usar bibliotecas comerciales o de código cerrado, pero si no aparece una respuesta mejor, por supuesto, honraré cualquier solución que funcione con una aceptación. Aceptaré la primera (razonablemente buena) respuesta de trabajo del tipo "1". Si aparecen respuestas de menor preferencia, esperaré unos días antes de aceptar la mejor entre ellas.

PD

Lanzaré un par de preguntas similares para otros navegadores. Dado que creo que los navegadores son bastante diferentes en los argumentos de la línea de comandos que digieren, la forma en que se inician los subprocesos y subprocesos, creo que esto tiene sentido.


Aquí hay un programa de muestra que de alguna manera puede demostrar la capacidad de una biblioteca de selenio para cumplir con lo que desea. Debe descargar la biblioteca de selenio y configurarla en su IDE antes de poder ejecutar este programa.

El programa te permite hacer clic en un botón. Luego, el navegador Firefox se abre automáticamente e inicia un sitio web en unos segundos. Espere mientras se carga el sitio web. Después de eso, puede cerrar el navegador Firefox. El programa también se cerrará automáticamente después de 2 segundos.

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 se utiliza principalmente para probar la automatización de aplicaciones web. Puede abrir navegadores directamente y leer el contenido html que contiene. Consulte http://www.seleniumhq.org/ para obtener información adicional.