Como lidar com iFrames no Selenium Webdriver: switchTo()

iFrame no Selenium Webdriver

iFrame no Selenium Webdriver é uma página da web ou um quadro embutido incorporado em outra página da web ou um documento HTML incorporado em outro documento HTML. O iframe é frequentemente usado para adicionar conteúdo de outras fontes, como um anúncio, a uma página da web. O iframe é definido com oiframe> tag.

Como identificar o iFrame

Não podemos detectar os frames apenas vendo a página ou inspecionando o Firebug.

Observe a imagem abaixo, o anúncio exibido é um Iframe, não podemos localizar ou reconhecer isso apenas inspecionando usando o Firebug. Então a questão é como você pode identificar o iframe?

Identifique o iframe
Como identificar o iframe usando Selenium WebDriver

Podemos identificar os frames no Selenium usando os métodos abaixo:

  • Clique com o botão direito no elemento. Se você encontrar a opção 'Este quadro', então é um iframe. (Consulte o diagrama acima)
  • Clique com o botão direito na página e clique em 'Exibir código-fonte da página' e pesquise com o 'iframe'. Se você encontrar qualquer nome de tag com o 'iframe', significa que a página consiste em um iframe.

No diagrama acima, você pode ver que 'Este quadro'está disponível ao clicar com o botão direito, então agora temos certeza de que é um iframe.

Podemos até identificar o número total de iframes usando o snippet abaixo.

Int size = driver.findElements(By.tagName("iframe")).size();

Como lidar com frames no Selenium usando comandos WebDriver

Basicamente, podemos alternar os elementos e lidar com frames no Selenium de 3 maneiras.

  • Por índice
  • Por nome ou ID
  • Por elemento da web

Método 1: mudar para o quadro por índice

Índice é um dos atributos para manipulação de quadros no Selenium através do qual podemos mudar para ele.

O índice do iframe começa com '0'.

Suponha que se houver 100 frames na página, podemos mudar para frame no Selenium usando index.

  • driver.switchTo().frame(0);
  • driver.switchTo().frame(1);

Método 2: mudar para o quadro por nome ou ID

Nome e ID são atributos para manipulação de frames no Selenium através dos quais podemos mudar para o iframe.

  • driver.switchTo().frame("iframe1");
  • driver.switchTo().frame("id of the element");

Exemplo de mudança para iframe por meio de ID:

para o quadro por Web Element

Podemos acessar este iframe através do URL abaixo: https://demo.guru99.com/test/guru99home/

Lidar com frames no Selenium usando comandos do WebDriver

É impossível clicar no iframe diretamente através XPath já que é um iframe. Primeiro temos que mudar para o quadro e depois podemos clicar usando o xpath.

Passo 1)

WebDriver driver = new FirefoxDriver();

driver.get("https://demo.guru99.com/test/guru99home/");

driver.manage().window().maximize();

  • Inicializamos o Firefox motorista.
  • Navegue até o site “guru99” que consiste no iframe.
  • Maximizou a janela.

Passo 2)

driver.switchTo().frame("a077aa5e");
  • Nesta etapa precisamos descobrir o id do iframe inspecionando através do Firebug.
  • Em seguida, mude para o iframe através do ID.

Passo 3)

driver.findElement(By.xpath("html/body/a/img")).click();
  • Aqui precisamos descobrir o xpath do elemento a ser clicado.
  • Clique no elemento usando o comando do driver da web mostrado acima.

Aqui está o código completo:

public class SwitchToFrame_ID {
public static void main(String[] args) {

		WebDriver driver = new FirefoxDriver(); //navigates to the Browser
	    driver.get("https://demo.guru99.com/test/guru99home/"); 
	       // navigates to the page consisting an iframe

	       driver.manage().window().maximize();
	       driver.switchTo().frame("a077aa5e"); //switching the frame by ID

			System.out.println("********We are switch to the iframe*******");
     		driver.findElement(By.xpath("html/body/a/img")).click();
  		    //Clicks the iframe
       
  			System.out.println("*********We are done***************");
      }
}		

Saída:

O navegador navega até a página que consiste no iframe acima e clica no iframe.

Método 3: mudar para o quadro por elemento da Web

Podemos até mudar para o iframe usando o elemento web.

  • driver.switchTo().frame(WebElement);

Como voltar para o quadro principal

Temos que sair do iframe.

Para voltar ao quadro pai, você pode usar switchTo().parentFrame() ou, se quiser voltar ao quadro principal (ou à maioria dos pais), pode usar switchTo().defaultContent();

	    driver.switchTo().parentFrame();
	    driver.switchTo().defaultContent();

Como mudar o quadro, se NÃO PODEMOS mudar usando ID ou Elemento Web:

Suponha que haja 100 frames na página e não haja nenhum ID disponível, neste caso, simplesmente não sabemos de qual iframe o elemento necessário está sendo carregado (é o caso quando não sabemos o índice do frame também).

A solução para a preocupação acima é: devemos encontrar o índice do iframe através do qual o elemento está sendo carregado e então mudar para o iframe através do índice.

Abaixo estão as etapas para encontrar o índice do quadro pelo qual o elemento está sendo carregado usando o snippet abaixo

Passo 1)

WebDriver driver = new FirefoxDriver();
driver.get("https://demo.guru99.com/test/guru99home/");
driver.manage().window().maximize();
  • Inicialize o Firefox motorista.
  • Navegue até o site “guru99” que contém o iframe.
  • Maximizou a janela.

Passo 2)

int size = driver.findElements(By.tagName("iframe")).size();
  • O código acima encontra o número total de iframes presentes na página usando o tagname ‘iframe’.

Passo 3)

Objetivo para esta etapa seria descobrir o índice do iframe.

for(int i=0; i<=size; i++){
	driver.switchTo().frame(i);
	int total=driver.findElements(By.xpath("html/body/a/img")).size();
	System.out.println(total);
	    driver.switchTo().defaultContent();}

Acima do “forloop” itera todos os iframes na página e imprime '1' se nosso iframe necessário for encontrado, caso contrário retorna '0'.

Aqui está o código completo até a etapa 3:

public class IndexOfIframe {
public static void main(String[] args) {
	    WebDriver driver = new FirefoxDriver();
	    driver.get("https://demo.guru99.com/test/guru99home/");  
	    driver.manage().window().maximize();
	    //driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
	    int size = driver.findElements(By.tagName("iframe")).size();

	    for(int i=0; i<=size; i++){
		driver.switchTo().frame(i);
		int total=driver.findElements(By.xpath("html/body/a/img")).size();
		System.out.println(total);
	    driver.switchTo().defaultContent();}}}

Execute este programa e a saída seria como abaixo:

Saída:

1
0
0
0	
0
0

Verifique a saída, você pode encontrar a série de 0 e 1.

  • Onde quer que você encontre o '1' na saída, esse é o índice do quadro pelo qual o elemento está sendo carregado.
  • Como o índice do iframe começa com '0' se você encontrar o 1 no 1stlugar, então o índice é 0.
  • Se você encontrar 1 em 3rd lugar, o índice é 2.

Podemos comentar o loop for, assim que encontrarmos o índice.

Passo 4)

driver.switchTo().frame(0);
  • Depois de encontrar o índice do elemento, você pode alternar o quadro usando o comando acima.
  • driver.switchTo().frame(índice encontrado na Etapa 3);

Passo 5)

driver.findElement(By.xpath("html/body/a/img")).click();
  • O código acima clicará no iframe ou elemento do iframe.

Então o código completo ficaria como abaixo:

public class SwitchToframe   {
public static void main(String[] args) throws NoSuchElementException{
	    WebDriver driver = new FirefoxDriver();
	    driver.get("https://demo.guru99.com/test/guru99home/");  
	    driver.manage().window().maximize();
	    //int size = driver.findElements(By.tagName("iframe")).size();
	
	/*for(int i=0; i<=size; i++){
	    driver.switchTo().frame(i);
	    int total=driver.findElements(By.xpath("html/body/a/img")).size();
		System.out.println(total);
	    driver.switchTo().defaultContent(); //switching back from the iframe
	 }*/
	            
		//Commented the code for finding the index of the element
	    driver.switchTo().frame(0); //Switching to the frame
		System.out.println("********We are switched to the iframe*******");
		driver.findElement(By.xpath("html/body/a/img")).click();
		
		//Clicking the element in line with Advertisement
	    System.out.println("*********We are done***************");
	        }
	    }

Saída:

O navegador navega até a página que consiste no iframe acima e clica no iframe.

Conceito de quadros aninhados em Selenium

Vamos supor que existam dois quadros um dentro do outro como mostrado na imagem abaixo e nosso requisito é imprimir o texto no quadro externo e no quadro interno.

No caso de quadros aninhados,

  • Primeiramente devemos mudar para o quadro externo pelo Índice ou ID do iframe
  • Assim que mudarmos para o quadro externo, podemos encontrar o número total de iframes dentro do quadro externo e
  • Podemos mudar para o quadro interno por qualquer um dos métodos conhecidos.

Ao sair do quadro, devemos sair na mesma ordem em que entramos nele, primeiro do quadro interno e depois do quadro externo.

Conceito de quadros aninhados em Selenium
iFrames aninhados no Selenium WebDriver

O código HTML para o quadro aninhado acima é mostrado abaixo.

Conceito de quadros aninhados em Selenium

O código HTML acima explica claramente a tag iframe (destacada em verde) dentro de outra tag iframe, indicando a presença de iframes aninhados.

Abaixo estão as etapas para mudar para o quadro externo e imprimir o texto nos quadros externos:

Passo 1)

	WebDriver driver=new FirefoxDriver();
	    driver.get("Url");
	    driver.manage().window().maximize();
	    driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
	    int size = driver.findElements(By.tagName("iframe")).size();
	    System.out.println("Total Frames --" + size);
	    
		// prints the total number of frames 
		driver.switchTo().frame(0); // Switching the Outer Frame    		
	    System.out.println (driver.findElement(By.xpath("xpath of the outer element ")).getText());
  • Mude para a moldura externa.
  • Imprime o texto no quadro externo.

Assim que mudarmos para o quadro externo, devemos saber se algum quadro interno está presente dentro do quadro externo.

Passo 2)

size = driver.findElements(By.tagName("iframe")).size();
    // prints the total number of frames inside outer frame           
    System.out.println("Total Frames --" + size);
  • Encontra o número total de iframes dentro do quadro externo.
  • Se o tamanho for encontrado como '0', então não há moldura interna dentro da moldura.

Passo 3)

driver.switchTo().frame(0); // Switching to innerframe
System.out.println(driver.findElement(By.xpath("xpath of the inner element ")).getText());
  • Mude para a moldura interna
  • Imprime o texto no quadro interno.

Aqui está o código completo:

public class FramesInsideFrames {
public static void main(String[] args) {
WebDriver driver=new FirefoxDriver();
	    driver.get("Url");
	    driver.manage().window().maximize();
	    driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

	    int size = driver.findElements(By.tagName("iframe")).size();
	    System.out.println("Total Frames --" + size);
               
		// prints the total number of frames 
		driver.switchTo().frame(0); // Switching the Outer Frame    		
	    System.out.println (driver.findElement(By.xpath("xpath of the outer element ")).getText());

		//Printing the text in outer frame
		size = driver.findElements(By.tagName("iframe")).size();
	    // prints the total number of frames inside outer frame           
                                                                                                          
	    System.out.println("Total Frames --" + size);
	    driver.switchTo().frame(0); // Switching to innerframe
	    System.out.println(driver.findElement(By.xpath("xpath of the inner element ")).getText());
		
		//Printing the text in inner frame
		driver.switchTo().defaultContent();
	}
}

saída:

A saída do código acima imprimiria o texto no quadro interno e no quadro externo.