在相同的浏览器会话中使用Selenium

时间:2013-01-24 20:45:48

标签: testing selenium junit

import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.Select;

public class Test1 {
  private WebDriver driver;
  private String baseUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();

  @Before
  public void setUp() throws Exception {
    System.setProperty("webdriver.ie.driver",  "D:/Development/ProgrammingSoftware/Testing/IEDriverServer.exe");

    WebDriver driver = new InternetExplorerDriver();
    baseUrl = "http://seleniumhq.org/";
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  }

  @Test
  public void test1() throws Exception {
    driver.get(baseUrl + "/download/");
    driver.findElement(By.linkText("Latest Releases")).click();
    driver.findElement(By.linkText("All variants of the Selenium Server: stand-alone, jar with dependencies and sources.")).click();
  }

  @After
  public void tearDown() throws Exception {
    driver.quit();
    String verificationErrorString = verificationErrors.toString();
    if (!"".equals(verificationErrorString)) {
      fail(verificationErrorString);
    }
  }

  private boolean isElementPresent(By by) {
    try {
      driver.findElement(by);
      return true;
    } catch (NoSuchElementException e) {
      return false;
    }
  }

  private String closeAlertAndGetItsText() {
    try {
      Alert alert = driver.switchTo().alert();
      if (acceptNextAlert) {
        alert.accept();
      } else {
        alert.dismiss();
      }
      return alert.getText();
    } finally {
      acceptNextAlert = true;
    }
  }
}

我想让IE具有相同的会话,但此代码始终打开IE的新实例。我是如何得到这项工作的?

2 个答案:

答案 0 :(得分:2)

我认为不可能将驱动程序附加到现有会话。

如果您已经完成了测试方法的执行,并且您想要执行另一个类或包中存在的另一个测试方法,请通过将当前驱动程序传递给它来调用该方法,以便您可以使用当前的实例那边的司机。

答案 1 :(得分:0)

这个问题过去已经问过好几次了,我要回答的问题与最近的问题甚至还没有接近。但是我仍然要继续发布答案,因为最近我被与同一个浏览器会话相关的问题所困扰。我将如何利用已经打开的浏览器,以便继续测试运行,而不必从头开始。在浏览成千上万的页面后,当遇到重新启动Selenium测试的问题时,在某些情况下甚至会很费力。相反,我只是想知道“银弹在哪里?”。最后,我看到了由“ http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/”撰写的文章之一。但是,仍然缺少一些链接。因此,我想在一个合适的例子的帮助下对此进行阐述。 在以下代码段中,我试图启动SeleniumHQ并在Chrome浏览器的Selenium会话中单击“下载”链接。

    System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
        ChromeDriver driver = new ChromeDriver();
        HttpCommandExecutor executor = (HttpCommandExecutor) 
        driver.getCommandExecutor();
        URL url = executor.getAddressOfRemoteServer();
        SessionId session_id = driver.getSessionId();
        storeSessionAttributesToFile("Id",session_id.toString());
        storeSessionAttributesToFile("URL",url.toString());
        driver.get("https://docs.seleniumhq.org/");
        WebElement download = driver.findElementByLinkText("Download");
        download.click();

如果您阅读上述代码,则将捕获Selenium远程服务器的URL和当前硒(浏览器)会话的会话ID,并将其写入属性文件。 现在,尽管我停止了当前的测试运行,但是如果我需要继续在相同的浏览器窗口/会话中执行,我所要做的就是在上述代码段中注释掉的第一个会话下面的代码进行注释,并从下面的代码继续进行测试:

System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
  //ChromeDriver driver = new ChromeDriver();
  //HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
 //URL url = executor.getAddressOfRemoteServer();
//SessionId session_id = driver.getSessionId();
//storeSessionAttributesToFile("Id",session_id.toString());
//      storeSessionAttributesToFile("URL",url.toString());
//      driver.get("https://docs.seleniumhq.org/");
//      WebElement download = driver.findElementByLinkText("Download");
//      download.click();
//Attaching to the session
    String existingSession = readSessionId("Id");
    String url1 = readSessionId("URL");
    URL existingDriverURL = new URL(url1);
    RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
    WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
    previousReleases.click();

现在您可能必须重构并重命名驱动程序对象(即使保留名称仍然可以使用,但我只是想区分将其附加到现有驱动程序和启动该驱动程序)。在上面的代码块中,我在读取并分配了URL和sessionid之后继续测试,并从session创建驱动程序以继续利用浏览器和session。 请查看下面的完整代码:

package org.openqa.selenium.example;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Collections;
import java.util.Properties;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.Response;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.W3CHttpCommandCodec;
import org.openqa.selenium.remote.http.W3CHttpResponseCodec;

public class AttachingToSession {

public static String SESSION_FILE = "C:\\example\\Session.Properties";
public static Properties prop = new Properties();

public static void main(String[] args) throws Exception {
    System.setProperty("webdriver.chrome.driver","C:\\Selenium\\chromedriver.exe");
//First Session
    ChromeDriver driver = new ChromeDriver();
    HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor();
    URL url = executor.getAddressOfRemoteServer();
    SessionId session_id = driver.getSessionId();
    storeSessionAttributesToFile("Id",session_id.toString());
    storeSessionAttributesToFile("URL",url.toString());
    driver.get("https://docs.seleniumhq.org/");
    WebElement download = driver.findElementByLinkText("Download");
    download.click();
//Attaching to the session
    String existingSession = readSessionId("Id");
    String url1 = readSessionId("URL");
    URL existingDriverURL = new URL(url1);
    RemoteWebDriver attachToDriver = createDriverFromSession(existingSession, existingDriverURL);
    WebElement previousReleases = attachToDriver.findElementByLinkText("Previous Releases");
    previousReleases.click();
}

public static RemoteWebDriver createDriverFromSession(final String sessionId, URL command_executor){
    CommandExecutor executor = new HttpCommandExecutor(command_executor) {

        @Override
        public Response execute(Command command) throws IOException {
            Response response = null;
            if (command.getName() == "newSession") {
                response = new Response();
                response.setSessionId(sessionId);
                response.setStatus(0);
                response.setValue(Collections.<String, String>emptyMap());
                try {
                    Field commandCodec = null;
                    commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec");
                    commandCodec.setAccessible(true);
                    commandCodec.set(this, new W3CHttpCommandCodec());

                    Field responseCodec = null;
                    responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec");
                    responseCodec.setAccessible(true);
                    responseCodec.set(this, new W3CHttpResponseCodec());
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            } else {
                response = super.execute(command);
            }
            return response;
        }
    };

    return new RemoteWebDriver(executor, new DesiredCapabilities());
}


public static void storeSessionAttributesToFile(String key,String value) throws Exception{
        OutputStream output = null;
        try{
            output = new FileOutputStream(SESSION_FILE);
            //prop.load(output);
            prop.setProperty(key, value);
            prop.store(output, null);
        }
        catch(IOException e){
            e.printStackTrace();
        }
        finally {
            if(output !=null){
                output.close();
            }
        }

}

public static String readSessionId(String ID) throws Exception{

    Properties prop = new Properties();
    InputStream input = null;
    String SessionID = null;
    try {
        input = new FileInputStream(SESSION_FILE);
        // load a properties file
        prop.load(input);
        // get the property value and print it out
        System.out.println(prop.getProperty(ID));
        SessionID = prop.getProperty(ID);
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return SessionID;
}
}