HAR
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.agile611.trainings.webdriver</groupId>
|
<groupId>com.agile611.trainings.webdriver</groupId>
|
||||||
<artifactId>cursoSeleniumWebdriver</artifactId>
|
<artifactId>cursoSeleniumWebdriver</artifactId>
|
||||||
<version>19.08.15</version>
|
<version>26.04.23</version>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -60,5 +60,10 @@
|
|||||||
<artifactId>hamcrest-core</artifactId>
|
<artifactId>hamcrest-core</artifactId>
|
||||||
<version>2.2</version>
|
<version>2.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.lightbody.bmp</groupId>
|
||||||
|
<artifactId>browsermob-core</artifactId>
|
||||||
|
<version>2.1.5</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 279 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,10 +0,0 @@
|
|||||||
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
|
|
||||||
<suite name="StartUsingWebDriver test examples"
|
|
||||||
allow-return-values="true" verbose="1"
|
|
||||||
parallel="tests">
|
|
||||||
<test name="all" parallel="classes" thread-count="4" time-out="240000">
|
|
||||||
<packages>
|
|
||||||
<package name="com.agile611.testng.webdriver.*"/>
|
|
||||||
</packages>
|
|
||||||
</test>
|
|
||||||
</suite>
|
|
||||||
@@ -22,13 +22,13 @@ public class BaseTest {
|
|||||||
if (browser != null && browser.equalsIgnoreCase("firefox")) {
|
if (browser != null && browser.equalsIgnoreCase("firefox")) {
|
||||||
FirefoxOptions options = new FirefoxOptions();
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
System.setProperty("webdriver.gecko.driver",
|
System.setProperty("webdriver.gecko.driver",
|
||||||
"src" + File.separator + "main"
|
"src" + File.separator + "test"
|
||||||
+ File.separator + "resources"
|
+ File.separator + "resources"
|
||||||
+ File.separator + "geckodriver-macos");
|
+ File.separator + "geckodriver-macos");
|
||||||
driver = new FirefoxDriver(options);
|
driver = new FirefoxDriver(options);
|
||||||
} else {
|
} else {
|
||||||
ChromeOptions options = new ChromeOptions();
|
ChromeOptions options = new ChromeOptions();
|
||||||
System.setProperty("webdriver.chrome.driver", "src" + File.separator + "main" + File.separator + "resources" + File.separator + "chromedriver-macos");
|
System.setProperty("webdriver.chrome.driver", "src" + File.separator + "test" + File.separator + "resources" + File.separator + "chromedriver-macos");
|
||||||
driver = new ChromeDriver(options);
|
driver = new ChromeDriver(options);
|
||||||
}
|
}
|
||||||
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
|
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
|
||||||
|
|||||||
@@ -1,39 +1,89 @@
|
|||||||
package com.agile611.testng.webdriver;
|
package com.agile611.testng.webdriver;
|
||||||
|
|
||||||
import java.io.File;
|
import net.lightbody.bmp.BrowserMobProxy;
|
||||||
import java.util.List;
|
import net.lightbody.bmp.BrowserMobProxyServer;
|
||||||
|
import net.lightbody.bmp.client.ClientUtil;
|
||||||
import org.openqa.selenium.By;
|
import net.lightbody.bmp.core.har.Har;
|
||||||
|
import net.lightbody.bmp.core.har.HarEntry;
|
||||||
|
import org.openqa.selenium.Proxy;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||||
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.AfterMethod;
|
import org.testng.annotations.AfterMethod;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BrokenImages {
|
public class BrokenImages {
|
||||||
WebDriver driver;
|
WebDriver driver;
|
||||||
|
BrowserMobProxy proxy;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
// 1. Iniciar el servidor Proxy localmente
|
||||||
|
proxy = new BrowserMobProxyServer();
|
||||||
|
proxy.start(0); // El puerto 0 le dice que busque cualquier puerto libre
|
||||||
|
|
||||||
|
// 2. Crear el objeto Proxy de Selenium a partir del BrowserMob
|
||||||
|
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
|
||||||
|
|
||||||
|
// 3. Inyectar el proxy en las opciones de Firefox
|
||||||
FirefoxOptions options = new FirefoxOptions();
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
|
options.setProxy(seleniumProxy);
|
||||||
|
|
||||||
|
// Nota: Si usas Selenium 4.6+, esta línea ya no es necesaria gracias a Selenium Manager
|
||||||
System.setProperty("webdriver.gecko.driver",
|
System.setProperty("webdriver.gecko.driver",
|
||||||
"src" + File.separator + "main"
|
"src" + File.separator + "test"
|
||||||
+ File.separator + "resources"
|
+ File.separator + "resources"
|
||||||
+ File.separator + "geckodriver-macos");
|
+ File.separator + "geckodriver-macos");
|
||||||
|
|
||||||
driver = new FirefoxDriver(options);
|
driver = new FirefoxDriver(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
driver.quit();
|
// Es crucial apagar ambos servicios para no dejar procesos huérfanos
|
||||||
|
if (driver != null) {
|
||||||
|
driver.quit();
|
||||||
|
}
|
||||||
|
if (proxy != null) {
|
||||||
|
proxy.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void allImagesLoaded() {
|
public void allImagesLoaded() {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_imagenes");
|
||||||
|
|
||||||
|
// 5. Navegar a la página (el proxy registrará todo el tráfico)
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/broken_images");
|
driver.navigate().to("http://the-internet.herokuapp.com/broken_images");
|
||||||
List<WebElement> images = driver.findElements(By.tagName("img"));
|
|
||||||
// Simplified test, no proxy check
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
boolean hasBrokenImages = false;
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
String url = entry.getRequest().getUrl();
|
||||||
|
int statusCode = entry.getResponse().getStatus();
|
||||||
|
|
||||||
|
// Filtramos para evaluar solo los recursos que son imágenes
|
||||||
|
if (url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".gif")) {
|
||||||
|
if (statusCode == 404) {
|
||||||
|
System.err.println("❌ Imagen rota detectada (404): " + url);
|
||||||
|
hasBrokenImages = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("✅ Imagen cargada correctamente (" + statusCode + "): " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 8. El test fallará si al menos una imagen devolvió 404
|
||||||
|
Assert.assertFalse(hasBrokenImages, "Se encontraron imágenes con error 404 en la página.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ public class DisappearingElementsTest extends BaseTest {
|
|||||||
public void testApp() throws InterruptedException {
|
public void testApp() throws InterruptedException {
|
||||||
driver.navigate().to("https://the-internet.herokuapp.com/disappearing_elements");
|
driver.navigate().to("https://the-internet.herokuapp.com/disappearing_elements");
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
|
System.out.println("Iteración: " + (i + 1));
|
||||||
WebElement elementsDelMenu =
|
WebElement elementsDelMenu =
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.xpath(".//*[@id='content']/div/ul/li[last()]"));
|
By.xpath(".//*[@id='content']/div/ul/li[last()]"));
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
package com.agile611.testng.webdriver;
|
package com.agile611.testng.webdriver;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.WebElement;
|
import org.openqa.selenium.WebElement;
|
||||||
import org.openqa.selenium.chrome.ChromeDriver;
|
import org.openqa.selenium.chrome.ChromeDriver;
|
||||||
@@ -9,45 +16,49 @@ import org.testng.annotations.AfterMethod;
|
|||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
|
||||||
|
|
||||||
public class DownloadTest extends BaseTest {
|
public class DownloadTest extends BaseTest {
|
||||||
File folder;
|
File folder;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
folder = new File("src" + File.separator + "main" + File.separator + "resources" + File.separator + UUID.randomUUID().toString());
|
folder = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + UUID.randomUUID().toString());
|
||||||
//Chrome
|
|
||||||
System.setProperty("webdriver.chrome.driver", "src" + File.separator + "main" + File.separator + "resources" + File.separator + "chromedriver-macos");
|
|
||||||
String downloadFilepath = folder.getAbsolutePath();
|
String downloadFilepath = folder.getAbsolutePath();
|
||||||
|
|
||||||
|
//Chrome
|
||||||
|
System.setProperty("webdriver.chrome.driver", "src" + File.separator + "test" + File.separator + "resources" + File.separator + "chromedriver-macos");
|
||||||
|
|
||||||
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
|
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
|
||||||
chromePrefs.put("profile.default_content_settings.popups", 0);
|
chromePrefs.put("profile.default_content_settings.popups", 0);
|
||||||
chromePrefs.put("download.default_directory", downloadFilepath);
|
chromePrefs.put("download.default_directory", downloadFilepath);
|
||||||
ChromeOptions options = new ChromeOptions();
|
ChromeOptions options = new ChromeOptions();
|
||||||
options.setExperimentalOption("prefs", chromePrefs);
|
options.setExperimentalOption("prefs", chromePrefs);
|
||||||
options.setAcceptInsecureCerts(true);
|
options.setAcceptInsecureCerts(true);
|
||||||
|
//options.addArguments("--headless");
|
||||||
driver = new ChromeDriver(options);
|
driver = new ChromeDriver(options);
|
||||||
|
|
||||||
//Firefox
|
//Firefox
|
||||||
/*DesiredCapabilities capabilities = DesiredCapabilities.firefox();
|
// 1. Configurar el perfil de Firefox
|
||||||
|
/*FirefoxProfile profile = new FirefoxProfile();
|
||||||
System.setProperty("webdriver.gecko.driver",
|
System.setProperty("webdriver.gecko.driver",
|
||||||
"src" + File.separator + "main"
|
"src" + File.separator + "test"
|
||||||
+ File.separator + "resources"
|
+ File.separator + "resources"
|
||||||
+ File.separator + "geckodriver-macos");
|
+ File.separator + "geckodriver-macos");
|
||||||
FirefoxProfile profile = new FirefoxProfile();
|
|
||||||
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;application/csv;text/csv;application/vnd.ms-excel;");
|
profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream;application/csv;text/csv;application/vnd.ms-excel;");
|
||||||
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
|
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
|
||||||
profile.setPreference("browser.download.manager.showWhenStarting", false);
|
profile.setPreference("browser.download.manager.showWhenStarting", false);
|
||||||
profile.setPreference("browser.download.folderList", 2);
|
profile.setPreference("browser.download.folderList", 2);
|
||||||
profile.setPreference("browser.download.dir", folder.getAbsolutePath());
|
profile.setPreference("browser.download.dir", downloadFilepath);
|
||||||
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
|
|
||||||
driver = new FirefoxDriver(capabilities);*/
|
// 2. Usar FirefoxOptions en lugar de DesiredCapabilities
|
||||||
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
|
options.setProfile(profile);
|
||||||
|
|
||||||
|
// Opcional: Si necesitas ejecutarlo en modo incógnito o sin interfaz gráfica (headless)
|
||||||
|
//options.addArguments("-headless");
|
||||||
|
|
||||||
|
// 3. Inicializar el driver
|
||||||
|
// NOTA: Ya no necesitas System.setProperty para el geckodriver.
|
||||||
|
driver = new FirefoxDriver(options);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class DynamicContentTest extends BaseTest {
|
|||||||
By.xpath(".//*[@id='content']/div[3]/div[2]"));
|
By.xpath(".//*[@id='content']/div[3]/div[2]"));
|
||||||
String urlImatge1 = imatge1.getAttribute("src");
|
String urlImatge1 = imatge1.getAttribute("src");
|
||||||
String texttotal1 = text1.getText();
|
String texttotal1 = text1.getText();
|
||||||
driver.navigate().refresh();
|
driver.navigate().refresh(); //Regenero el DOM completo
|
||||||
imatge1 =
|
imatge1 =
|
||||||
driver.findElement(
|
driver.findElement(
|
||||||
By.xpath(".//*[@id='content']/div[3]/div[1]/img"));
|
By.xpath(".//*[@id='content']/div[3]/div[1]/img"));
|
||||||
|
|||||||
@@ -6,26 +6,25 @@ import org.openqa.selenium.WebElement;
|
|||||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
public class DynamicControlsTest extends BaseTest {
|
public class DynamicControlsTest extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void titleTest() {
|
public void titleTest() throws InterruptedException {
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/dynamic_controls");
|
driver.navigate().to("http://the-internet.herokuapp.com/dynamic_controls");
|
||||||
WebElement checkbox = driver.findElement(By.id("checkbox"));
|
WebElement checkbox = driver.findElement(By.id("checkbox"));
|
||||||
assertTrue(checkbox.isDisplayed());
|
assertTrue(checkbox.isDisplayed());
|
||||||
checkbox.click();
|
checkbox.click();
|
||||||
WebElement removeBtn = driver.findElement(By.xpath("//*[@id='checkbox-example']/button"));
|
WebElement removeBtn = driver.findElement(By.xpath("//*[@id='checkbox-example']/button"));
|
||||||
removeBtn.click();
|
removeBtn.click();
|
||||||
List<WebElement> loading = driver.findElements(By.xpath("//*[@id='loading']/img"));
|
|
||||||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
|
||||||
wait.until(ExpectedConditions.or(
|
wait.until(ExpectedConditions.or(
|
||||||
ExpectedConditions.presenceOfElementLocated(By.id("loading")),
|
ExpectedConditions.presenceOfElementLocated(By.id("loading")),
|
||||||
ExpectedConditions.presenceOfElementLocated(By.id("message"))));
|
ExpectedConditions.presenceOfElementLocated(By.id("message"))));
|
||||||
|
WebElement message = driver.findElement(By.id("message"));
|
||||||
|
assertTrue(message.isDisplayed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ public class InfiniteScrollTest extends BaseTest {
|
|||||||
public void infiniteScrollTest() throws InterruptedException {
|
public void infiniteScrollTest() throws InterruptedException {
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/infinite_scroll");
|
driver.navigate().to("http://the-internet.herokuapp.com/infinite_scroll");
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
|
System.out.println("Iteración: " + (i + 1));
|
||||||
jse.executeScript("window.scrollTo(0, document.body.scrollHeight);");
|
jse.executeScript("window.scrollTo(0, document.body.scrollHeight);");
|
||||||
Thread.sleep(2500);
|
Thread.sleep(2500);
|
||||||
}
|
}
|
||||||
|
|||||||
117
src/test/java/com/agile611/testng/webdriver/MarcaHARTest.java
Normal file
117
src/test/java/com/agile611/testng/webdriver/MarcaHARTest.java
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
package com.agile611.testng.webdriver;
|
||||||
|
|
||||||
|
import net.lightbody.bmp.BrowserMobProxy;
|
||||||
|
import net.lightbody.bmp.BrowserMobProxyServer;
|
||||||
|
import net.lightbody.bmp.client.ClientUtil;
|
||||||
|
import net.lightbody.bmp.core.har.Har;
|
||||||
|
import net.lightbody.bmp.core.har.HarEntry;
|
||||||
|
import net.lightbody.bmp.core.har.HarNameValuePair;
|
||||||
|
import net.lightbody.bmp.core.har.HarRequest;
|
||||||
|
import net.lightbody.bmp.core.har.HarResponse;
|
||||||
|
|
||||||
|
import org.openqa.selenium.Proxy;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||||
|
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||||
|
import org.testng.annotations.AfterMethod;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MarcaHARTest {
|
||||||
|
WebDriver driver;
|
||||||
|
BrowserMobProxy proxy;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
// 1. Iniciar el servidor Proxy localmente
|
||||||
|
proxy = new BrowserMobProxyServer();
|
||||||
|
proxy.start(0); // El puerto 0 le dice que busque cualquier puerto libre
|
||||||
|
|
||||||
|
// 2. Crear el objeto Proxy de Selenium a partir del BrowserMob
|
||||||
|
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
|
||||||
|
|
||||||
|
// 3. Inyectar el proxy en las opciones de Firefox
|
||||||
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
|
options.setProxy(seleniumProxy);
|
||||||
|
|
||||||
|
// Nota: Si usas Selenium 4.6+, esta línea ya no es necesaria gracias a Selenium Manager
|
||||||
|
System.setProperty("webdriver.gecko.driver",
|
||||||
|
"src" + File.separator + "test"
|
||||||
|
+ File.separator + "resources"
|
||||||
|
+ File.separator + "geckodriver-macos");
|
||||||
|
|
||||||
|
driver = new FirefoxDriver(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterMethod
|
||||||
|
public void tearDown() {
|
||||||
|
// Es crucial apagar ambos servicios para no dejar procesos huérfanos
|
||||||
|
if (driver != null) {
|
||||||
|
driver.quit();
|
||||||
|
}
|
||||||
|
if (proxy != null) {
|
||||||
|
proxy.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void allImagesLoaded() throws InterruptedException {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_imagenes");
|
||||||
|
|
||||||
|
// 5. Navegar a la página (el proxy registrará todo el tráfico)
|
||||||
|
driver.navigate().to("http://www.marca.com");
|
||||||
|
|
||||||
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
Thread.sleep(15000);
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
HarRequest request = entry.getRequest();
|
||||||
|
HarResponse response = entry.getResponse();
|
||||||
|
|
||||||
|
System.out.println("==================================================");
|
||||||
|
System.out.println("🌐 URL: " + request.getUrl());
|
||||||
|
System.out.println("▶️ Método HTTP: " + request.getMethod());
|
||||||
|
System.out.println("◀️ Código de Estado: " + response.getStatus() + " " + response.getStatusText());
|
||||||
|
System.out.println("⏱️ Tiempo Total: " + entry.getTime() + " ms");
|
||||||
|
|
||||||
|
// 1. Extraer Cabeceras de la Petición (Request Headers)
|
||||||
|
System.out.println("\n📦 CABECERAS DE PETICIÓN:");
|
||||||
|
for (HarNameValuePair header : request.getHeaders()) {
|
||||||
|
System.out.println(" - " + header.getName() + ": " + header.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Extraer Cabeceras de la Respuesta (Response Headers)
|
||||||
|
System.out.println("\n📥 CABECERAS DE RESPUESTA:");
|
||||||
|
for (HarNameValuePair header : response.getHeaders()) {
|
||||||
|
System.out.println(" - " + header.getName() + ": " + header.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Extraer Información del Contenido
|
||||||
|
System.out.println("\n📄 DETALLES DEL CONTENIDO:");
|
||||||
|
System.out.println(" - Tipo MIME: " + response.getContent().getMimeType());
|
||||||
|
System.out.println(" - Tamaño del cuerpo: " + response.getContent().getSize() + " bytes");
|
||||||
|
|
||||||
|
// Opcional: Imprimir el texto de la respuesta (Cuidado, puede ser muy largo para HTML/JS)
|
||||||
|
// if (response.getContent().getText() != null) {
|
||||||
|
// System.out.println(" - Contenido: " + response.getContent().getText().substring(0, Math.min(response.getContent().getText().length(), 100)) + "...");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 4. Extraer Tiempos de Red (Timings)
|
||||||
|
System.out.println("\n⏳ DESGLOSE DE TIEMPOS:");
|
||||||
|
System.out.println(" - Bloqueado (Blocked): " + entry.getTimings().getBlocked() + " ms");
|
||||||
|
System.out.println(" - Resolución DNS: " + entry.getTimings().getDns() + " ms");
|
||||||
|
System.out.println(" - Conexión: " + entry.getTimings().getConnect() + " ms");
|
||||||
|
System.out.println(" - Espera al servidor (TTFB): " + entry.getTimings().getWait() + " ms");
|
||||||
|
System.out.println(" - Descarga de datos (Receive): " + entry.getTimings().getReceive() + " ms");
|
||||||
|
System.out.println("==================================================\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,15 +15,19 @@ import org.testng.annotations.Test;
|
|||||||
public class MultipleWindowsTest extends BaseTest {
|
public class MultipleWindowsTest extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multipleWindows() {
|
public void multipleWindows() throws InterruptedException {
|
||||||
driver.get("http://the-internet.herokuapp.com/windows");
|
driver.get("http://the-internet.herokuapp.com/windows");
|
||||||
|
|
||||||
String originalWindow = driver.getWindowHandle();
|
String originalWindow = driver.getWindowHandle();
|
||||||
|
|
||||||
driver.findElement(By.cssSelector(".example a")).click();
|
driver.findElement(By.xpath("//a[@href=\'/windows/new\']")).click();
|
||||||
|
|
||||||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
|
||||||
|
Thread.sleep(3000); // Temas del Firefox
|
||||||
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
|
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
|
||||||
|
// numberOfWindowsToBe de Firefox no se interpreta bien, por eso el sleep
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
String newWindow = "";
|
String newWindow = "";
|
||||||
for (String handle : driver.getWindowHandles()) {
|
for (String handle : driver.getWindowHandles()) {
|
||||||
@@ -45,8 +49,8 @@ public class MultipleWindowsTest extends BaseTest {
|
|||||||
driver.switchTo().window(originalWindow);
|
driver.switchTo().window(originalWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(dependsOnMethods = "multipleWindows")
|
||||||
public void multipleWindowsRedux() {
|
public void multipleWindowsRedux() throws InterruptedException {
|
||||||
driver.get("http://the-internet.herokuapp.com/windows");
|
driver.get("http://the-internet.herokuapp.com/windows");
|
||||||
|
|
||||||
String firstWindow = driver.getWindowHandle();
|
String firstWindow = driver.getWindowHandle();
|
||||||
@@ -54,8 +58,10 @@ public class MultipleWindowsTest extends BaseTest {
|
|||||||
|
|
||||||
driver.findElement(By.cssSelector(".example a")).click();
|
driver.findElement(By.cssSelector(".example a")).click();
|
||||||
|
|
||||||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
|
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
|
||||||
|
Thread.sleep(3000); // Temas de tiempos del Firefox
|
||||||
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
|
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
|
||||||
|
// numberOfWindowsToBe de Firefox no se interpreta bien, por eso el sleep
|
||||||
|
|
||||||
Set<String> allWindows = driver.getWindowHandles();
|
Set<String> allWindows = driver.getWindowHandles();
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +1,170 @@
|
|||||||
package com.agile611.testng.webdriver;
|
package com.agile611.testng.webdriver;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||||
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.AfterMethod;
|
import org.testng.annotations.AfterMethod;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
import org.openqa.selenium.Proxy;
|
||||||
|
|
||||||
|
import net.lightbody.bmp.BrowserMobProxy;
|
||||||
|
import net.lightbody.bmp.BrowserMobProxyServer;
|
||||||
|
import net.lightbody.bmp.client.ClientUtil;
|
||||||
|
import net.lightbody.bmp.core.har.Har;
|
||||||
|
import net.lightbody.bmp.core.har.HarEntry;
|
||||||
|
|
||||||
public class StatusCodesTest {
|
public class StatusCodesTest {
|
||||||
WebDriver driver;
|
WebDriver driver;
|
||||||
|
BrowserMobProxy proxy;
|
||||||
|
|
||||||
@BeforeMethod
|
@BeforeMethod
|
||||||
public void setUp() {
|
public void setUp() throws Exception {
|
||||||
|
// 1. Iniciar el servidor Proxy localmente
|
||||||
|
proxy = new BrowserMobProxyServer();
|
||||||
|
proxy.start(0); // El puerto 0 le dice que busque cualquier puerto libre
|
||||||
|
|
||||||
|
// 2. Crear el objeto Proxy de Selenium a partir del BrowserMob
|
||||||
|
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
|
||||||
|
|
||||||
|
// 3. Inyectar el proxy en las opciones de Firefox
|
||||||
FirefoxOptions options = new FirefoxOptions();
|
FirefoxOptions options = new FirefoxOptions();
|
||||||
|
options.setProxy(seleniumProxy);
|
||||||
|
|
||||||
|
// Nota: Si usas Selenium 4.6+, esta línea ya no es necesaria gracias a Selenium Manager
|
||||||
System.setProperty("webdriver.gecko.driver",
|
System.setProperty("webdriver.gecko.driver",
|
||||||
"src" + File.separator + "main"
|
"src" + File.separator + "test"
|
||||||
+ File.separator + "resources"
|
+ File.separator + "resources"
|
||||||
+ File.separator + "geckodriver-macos");
|
+ File.separator + "geckodriver-macos");
|
||||||
|
|
||||||
driver = new FirefoxDriver(options);
|
driver = new FirefoxDriver(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod
|
@AfterMethod
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
driver.quit();
|
// Es crucial apagar ambos servicios para no dejar procesos huérfanos
|
||||||
|
if (driver != null) {
|
||||||
|
driver.quit();
|
||||||
|
}
|
||||||
|
if (proxy != null) {
|
||||||
|
proxy.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ResourceNotFound404() {
|
public void ResourceNotFound404() {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_404");
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/404");
|
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/404");
|
||||||
// Simplified test, no proxy
|
|
||||||
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
boolean hasError404 = false;
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
String url = entry.getRequest().getUrl();
|
||||||
|
int statusCode = entry.getResponse().getStatus();
|
||||||
|
|
||||||
|
// Filtramos para evaluar solo los recursos que son imágenes
|
||||||
|
if (statusCode == 404) {
|
||||||
|
System.err.println("❌ 404 Detectado: " + url);
|
||||||
|
hasError404 = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("✅ Recurso cargado correctamente (" + statusCode + "): " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 8. El test fallará si al menos una imagen devolvió 404
|
||||||
|
Assert.assertTrue(hasError404, "Se encontraron recursos con error 404 en la página.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ResourceFound200() {
|
public void ResourceFound200() {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_200");
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/200");
|
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/200");
|
||||||
// Simplified test, no proxy
|
|
||||||
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
boolean hasError200 = false;
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
String url = entry.getRequest().getUrl();
|
||||||
|
int statusCode = entry.getResponse().getStatus();
|
||||||
|
|
||||||
|
// Filtramos para evaluar solo los recursos que son imágenes
|
||||||
|
if (statusCode == 200) {
|
||||||
|
System.err.println("✅ 200 Detectado: " + url);
|
||||||
|
hasError200 = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertTrue(hasError200, "Se encontraron recursos con 200 en la página.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ResourceRedirect301() {
|
public void ResourceRedirect301() {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_301");
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/301");
|
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/301");
|
||||||
// Simplified test, no proxy
|
|
||||||
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
boolean hasError301 = false;
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
String url = entry.getRequest().getUrl();
|
||||||
|
int statusCode = entry.getResponse().getStatus();
|
||||||
|
|
||||||
|
// Filtramos para evaluar solo los recursos que son imágenes
|
||||||
|
if (statusCode == 301) {
|
||||||
|
System.err.println("✅ 301 Detectado: " + url);
|
||||||
|
hasError301 = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertTrue(hasError301, "Se encontraron recursos con 301 en la página.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void ResourceError500() {
|
public void ResourceError500() {
|
||||||
|
// 4. Iniciar la captura de un nuevo archivo HAR
|
||||||
|
proxy.newHar("captura_500");
|
||||||
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/500");
|
driver.navigate().to("http://the-internet.herokuapp.com/status_codes/500");
|
||||||
// Simplified test, no proxy
|
|
||||||
|
// 6. Extraer el HAR generado
|
||||||
|
Har har = proxy.getHar();
|
||||||
|
|
||||||
|
// 7. Analizar las entradas de red
|
||||||
|
boolean hasError500 = false;
|
||||||
|
List<HarEntry> entries = har.getLog().getEntries();
|
||||||
|
|
||||||
|
for (HarEntry entry : entries) {
|
||||||
|
String url = entry.getRequest().getUrl();
|
||||||
|
int statusCode = entry.getResponse().getStatus();
|
||||||
|
|
||||||
|
// Filtramos para evaluar solo los recursos que son imágenes
|
||||||
|
if (statusCode == 500) {
|
||||||
|
System.err.println("✅ 500 Detectado: " + url);
|
||||||
|
hasError500 = true;
|
||||||
|
} else {
|
||||||
|
System.out.println("❌ Recurso NO cargado correctamente (" + statusCode + "): " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert.assertTrue(hasError500, "Se encontraron recursos con 500 en la página.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
Binary file not shown.
BIN
src/test/resources/chromedriver.exe
Normal file → Executable file
BIN
src/test/resources/chromedriver.exe
Normal file → Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/test/resources/geckodriver.exe
Executable file → Normal file
BIN
src/test/resources/geckodriver.exe
Executable file → Normal file
Binary file not shown.
Reference in New Issue
Block a user