Selenium multiple tabs at once

前端 未结 7 1421
孤城傲影
孤城傲影 2020-11-27 17:24

I\'m working with Selenium, and am wondering if it\'s possible to use multiple TABS at once? I do not want to use multiple browser instances (i.e., 2 copies of IE pun). IF I

相关标签:
7条回答
  • 2020-11-27 17:33

    Try with below code.

        String oldTab = driver.getWindowHandle();
        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
        ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
        newTab.remove(oldTab);
        driver.switchTo().window(newTab.get(0));
    
    0 讨论(0)
  • 2020-11-27 17:38

    To open multiple tabs:

    driver = new ChromeDriver();
    IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
    for (int i = 0; i < 10; i++)
    {                
      driver.Navigate().GoToUrl(this.baseURL);      
      jscript.ExecuteScript("window.open('{0}', '_blank');", this.baseURL);
    }
    

    Swich between them:

    for (int i = 0; i < driver.WindowHandles.Count; i++)
    { 
      driver.SwitchTo().Window(driver.WindowHandles[i])]);
    }
    
    0 讨论(0)
  • 2020-11-27 17:40

    It is possible to switch between individual tabs without having multiple browser instances.
    There is a difference how web driver handles different windows and how it handles different tabs.

    Case 1:
    In case there are multiple windows, then the following code can help:

    //Get the current window handle
    String windowHandle = driver.getWindowHandle();
    
    //Get the list of window handles
    ArrayList tabs = new ArrayList (driver.getWindowHandles());
    System.out.println(tabs.size());
    //Use the list of window handles to switch between windows
    driver.switchTo().window(tabs.get(0));
    
    //Switch back to original window
    driver.switchTo().window(mainWindowHandle);
    


    Case 2:
    In case there are multiple tabs in the same window, then there is only one window handle. Hence switching between window handles keeps the control in the same tab.
    In this case using Ctrl + \t (Ctrl + Tab) to switch between tabs is more useful.

    //Open a new tab using Ctrl + t
    driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
    //Switch between tabs using Ctrl + \t
    driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");
    

    Detailed sample code can be found here:
    http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html

    0 讨论(0)
  • 2020-11-27 17:42

    If there is a link that opens up a new window/tab, then you can use driver.switchTo().window();

    However, if you want to run something on multiple windows, then I recommend having multiple instances of webdriver. It is much easier to manage, and is supported (There are workarounds on opening a new tab/window, such as pressing a hotkey that opens a new window, but they aren't supported).

    If you are wanting to have multiple threads all act on the same driver instance, but different tabs, that is NOT possible.

    0 讨论(0)
  • 2020-11-27 17:46

    This will solve your problem in case ur working with selenium and nodejs.

    driver.get('https://www.google.com/')
      .then(_ =>
        driver.findElement(webdriver.By.tagName('body'))
      )
      .then(bodyElement => {
        bodyElement.sendKeys(webdriver.Key.chord(webdriver.Key.CONTROL, 't'))
      })
      .catch(err => {
        console.log(err);
      })
    
    0 讨论(0)
  • 2020-11-27 17:49

    I recently implemented a simple multi-thread utility that allows running tests on separate tabs on separate threads WITH JUST ONE WEBDRIVER INSTANCE. The problem with WebDriver is that it can focus only one tab (window) at a time. So, to do tests in multiple tabs, WebDriver must be focused separately on each of them. I'm sure my implementation is not perfect, but here it is (implementation in Kotlin):

    Usage:

    fun test() {
    
      val results = ParallelNavigator(webDriver, 
        listOf(
        ::test1, 
        ::test2, 
        ::test3
        )
      ).start()
    
      println(results)
      // Output: [Success, Failure: java.lang.RuntimeException: Some error, Success]
    
    }
    
    fun test1(pn: ParallelNavigator) {
    
      /* ... open url, find elements etc. so stuff */
    
      pn.resumeNext() // transfer flow to another unfinished thread (test2 if not finished)
    
      /* ... do more stuff */
    
      pn.resumeNext() // again transfer flow to another thread
    
    }
    
    fun test2(pn: ParallelNavigator) { /* ... */ }
    fun test3(pn: ParallelNavigator) { /* ... */ }
    

    Implementation:

    import org.openqa.selenium.JavascriptExecutor
    import org.openqa.selenium.WebDriver
    import org.openqa.selenium.support.ui.WebDriverWait
    import java.util.concurrent.locks.Condition
    import java.util.concurrent.locks.ReentrantLock
    import kotlin.concurrent.thread
    import kotlin.concurrent.withLock
    
    class ParallelNavigator(private val webDriver: WebDriver, executions: List<(ParallelNavigator) -> Unit>) {
    
        private val _executions: List<TabExecution> = executions.map { TabExecution(it) }
    
        private var currentExecutionIndex: Int = -1
    
        fun start(): List<Result> {
            createTabs()
            return runInternal()
        }
    
        fun resumeNext() {
            if (_executions.isEmpty()) {
                throw RuntimeException("No executions provided.")
            }
    
            val currentExecution: TabExecution? = if (currentExecutionIndex != -1) {
                _executions[currentExecutionIndex]
            } else null
    
            val unfinished = _executions.filter { !it.finished }
    
            if(unfinished.isEmpty()) {
                return
            }
    
            val nextExecutionIndex = if (currentExecutionIndex >= unfinished.lastIndex || currentExecutionIndex <= -1) {
                0
            } else {
                currentExecutionIndex + 1
            }
            val nextExecution = unfinished[nextExecutionIndex]
            currentExecutionIndex = nextExecutionIndex
            webDriver.switchTo().window(nextExecution.windowHandle)
            nextExecution.lock.withLock {
                nextExecution.condition.signal()
            }
            currentExecution?.lock?.withLock {
                if (!currentExecution.finished) {
                    currentExecution.condition.await()
                }
            }
        }
    
        sealed class Result {
            class Success : Result() {
                override fun toString(): String {
                    return "Success"
                }
            }
            class Failure(val ex: Throwable) : Result() {
                override fun toString(): String {
                    return "Failure: ${ex.javaClass.name}: ${ex.message}"
                }
            }
            class Unfinished : Result() {
                override fun toString(): String {
                    return "Unfinished"
                }
            }
        }
    
        data class TabExecution(
            val test: (ParallelNavigator) -> Unit,
            val lock: ReentrantLock = ReentrantLock(),
            var finished: Boolean = false
        ) {
            lateinit var windowHandle: String
            lateinit var condition: Condition
            lateinit var thread: Thread
        }
    
    
        private fun createTabs() = with(webDriver) {
            navigate().to("about:blank")
            val homeWindowHandle = windowHandle
            for (execution in _executions) {
                execution.windowHandle = openNewTab()
            }
            webDriver.switchTo().window(homeWindowHandle)
        }
    
        private fun runInternal(): List<Result> {
            val results = _executions.map { Result.Unfinished() as Result }.toMutableList()
            for (index in _executions.indices) {
                val execution = _executions[index]
                val condition = execution.lock.newCondition()
                execution.condition = condition
                execution.thread = thread(start = false) {
                    execution.lock.withLock {
                        condition.await()
                        try {
                            execution.test(this)
                            results[index] = Result.Success()
                        } catch (ex: Throwable) {
                            ex.printStackTrace()
                            results[index] = Result.Failure(ex)
                        }
                        execution.finished = true
                        currentExecutionIndex--
                        resumeNext()
                    }
                }
    
                execution.thread.start()
            }
    
            resumeNext() // run first execution
    
            for (execution in _executions) {
                execution.thread.join()
            }
    
            return results
        }
    
        fun waitForNewTabToOpen(oldWindowHandles: Set<String>) = with(webDriver) {
            waitForNewTabToOpen(oldWindowHandles, 10)
        }
    
        fun waitForNewTabToOpen(oldWindowHandles: Set<String>, seconds: Int) = with(webDriver) {
            WebDriverWait(webDriver, seconds.toLong()).until<Boolean> { WebDriver -> availableWindowHandles().size > oldWindowHandles.size }
        }
    
        fun availableWindowHandles(): Set<String> = with(webDriver) {
            return webDriver.getWindowHandles()
        }
    
        private fun getNewTabHandle(oldWindowHandles: Set<String>): String = with(webDriver) {
            waitForNewTabToOpen(oldWindowHandles)
            val newWindowHandles = availableWindowHandles().toMutableSet()
            newWindowHandles.removeAll(oldWindowHandles)
            return newWindowHandles.iterator().next()
        }
    
        fun openNewTab(): String = with(webDriver) {
            val oldHandles = availableWindowHandles()
            (webDriver as JavascriptExecutor).executeScript("Object.assign(document.createElement('a'), { target: '_blank', href: 'about:blank'}).click();")
            waitForNewTabToOpen(oldHandles)
            return getNewTabHandle(oldHandles)
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题