Como lidar com iFrames em Selenium Driver da Web: switchTo()
iFrame em Selenium Driver da Web
iFrame em Selenium Driver da Web é 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?
Podemos identificar os quadros em Selenium usando os métodos fornecidos 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 quadros em Selenium usando comandos WebDriver
Basicamente, podemos alternar os elementos e manipular os quadros em Selenium usando 3 maneiras.
- Por índice
- Por nome ou ID
- Por elemento da web
Método 1: mudar para o quadro por índice
O índice é um dos atributos para manipulação de quadros em Selenium através do qual podemos mudar para ele.
O índice do iframe começa com '0'.
Suponha que se houver 100 quadros na página, podemos mudar para o quadro na Selenium usando índice.
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 em Selenium através do qual 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/
É 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.
O código HTML para o quadro aninhado acima é mostrado abaixo.
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.