Compare commits

..

26 Commits

Author SHA1 Message Date
Guillem Hernandez Sola
5cbbca59d0 upload test fixed 2026-04-23 13:25:13 +02:00
Guillem Hernandez Sola
98b34c5434 Added test 2026-04-23 13:22:56 +02:00
Guillem Hernandez Sola
818ea0622f HAR 2026-04-23 12:45:01 +02:00
Guillem Hernandez Sola
797fa4b66f Added hovers improved 2026-04-21 13:29:41 +02:00
Guillem Hernandez Sola
399ecaff28 Added Manipuation hover duckduckgo 2026-04-21 12:35:46 +02:00
Guillem Hernandez Sola
68eae36331 Keyboards Test 2026-04-21 12:12:58 +02:00
Guillem Hernandez Sola
379246891e Dropdown & navigation Tests 2026-04-21 12:01:50 +02:00
Guillem Hernandez Sola
05e2bd88d2 DuckDuckGotest 2026-04-21 11:05:37 +02:00
Guillem Hernandez Sola
d39e439da8 Added all 2026-04-20 18:09:18 +02:00
Guillem Hernandez Sola
73c7b7a45b Added some fixes on nestedwindows 2026-04-20 17:09:33 +02:00
Guillem Hernandez Sola
822b916a23 Added some fixes 2026-04-20 13:31:09 +02:00
Guillem Hernandez Sola
2ea0dc239b Added all 2026-04-20 13:23:34 +02:00
Guillem Hernandez Sola
aa622511f4 Some fixes 2026-04-20 13:05:31 +02:00
Guillem Hernandez Sola
a1f79f41c6 Updated a 4.43.0 selenium-java 2026-04-20 12:26:24 +02:00
Guillem Hernandez Sola
3cd765934d Updated a 4.43.0 selenium-java 2026-04-20 12:21:01 +02:00
Guillem Hernandez Sola
da053e3e0f Added logo 2026-04-20 12:19:04 +02:00
Guillem Hernandez Sola
2f2225c2ff Remove extra space 2026-04-20 12:17:58 +02:00
Guillem Hernandez Sola
1a63263274 Update README with CC-SA license and VS Code recommendation 2026-04-20 12:15:41 +02:00
Guillem Hernandez Sola
9da46f7517 Step 6: Upgrade to Java 25 - Compile: SUCCESS 2026-04-20 11:45:39 +02:00
Guillem Hernandez Sola
ee05f412a7 Step 5: Upgrade to Java 21 - Compile: SUCCESS 2026-04-20 11:44:27 +02:00
Guillem Hernandez Sola
ce815cc883 Step 4: Upgrade to Java 17 - Compile: SUCCESS 2026-04-20 11:43:53 +02:00
Guillem Hernandez Sola
a3fcfadf38 Step 3: Upgrade Dependencies - Compile: SUCCESS 2026-04-20 11:43:03 +02:00
Guillem Hernandez Sola
5a8c6dc7c7 Added code 2026-04-20 10:58:55 +02:00
3bd53a06f6 Merge pull request 'solutions' (#1) from solutions into master
Reviewed-on: #1
2026-04-20 08:38:57 +00:00
Guillem Hernandez Sola
3afc442338 Cambio requisite a requisito 2020-06-30 19:42:21 +02:00
6c8f95889c Added all examples 2019-08-18 00:30:22 +02:00
57 changed files with 1530 additions and 110 deletions

BIN
.DS_Store vendored

Binary file not shown.

63
.gitignore vendored
View File

@@ -11,6 +11,45 @@
.idea/**/tasks.xml
.idea/dictionaries
# Created by https://www.toptal.com/developers/gitignore/api/macos
# Edit at https://www.toptal.com/developers/gitignore?templates=macos
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
# End of https://www.toptal.com/developers/gitignore/api/macos
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
@@ -20,6 +59,30 @@
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries

4
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "interactive"
}

View File

@@ -2,23 +2,31 @@
Código del curso de Selenium WebDriver de [Agile611](https://www.agile611.com)
## Pre-requisite:
## Pre-requisitos:
1. MacOS, Linux o Windows
2. [Java](https://www.oracle.com/technetwork/java/javase/downloads/index.html)
3. [Maven](https://maven.apache.org/download.cgi)
4. [Firefox](https://www.mozilla.org/en-US/firefox/new/) instalado
5. [Chrome](https://www.google.com/chrome/) instalado
6. [Intellij Idea](https://www.jetbrains.com/idea/) o el IDE de Java que más os guste
6. [Visual Studio Code](https://code.visualstudio.com/) o el IDE de Java que más os guste
Puedes encontrar el [curso completo aquí](https://www.agile611.com/cursos/agile/curso-online-selenium-webdriver-version-java/)
## Cómo ejecutar
1. Clona el repositorio
2. Ejecuta `mvn clean test` para correr los tests
3. Los tests usan Firefox y Chrome, asegúrate de que los drivers estén en el PATH o en src/main/resources
## Soporte
Este tutorial es de dominio público y lo ha realizado [Agile611](https://www.agile611.com) under WTFPL.
Este tutorial es de dominio público y lo ha realizado [Agile611](https://www.agile611.com) under CC-SA.
[![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-1.png)](http://www.wtfpl.net/)
[![CC BY-SA](https://licensebuttons.net/l/by-sa/4.0/88x31.png)](https://creativecommons.org/licenses/by-sa/4.0/)
Este README lo ha hecho [Guillem Hernández Sola](https://www.linkedin.com/in/guillemhs/) y también es de dominio público.
Podéis contactar a [Agile611](https://www.agile611.com) por [aquí](https://www.agile611.com/formulario-de-contacto/) para más detalles.
[![Agile611](https://www.agile611.com/wp-content/uploads/2020/09/cropped-logo-header.png)](http://www.agile611.com/)

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.testng:testng:6.9.9" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.48" level="project" />
<orderEntry type="library" name="Maven: org.apache.ant:ant:1.7.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.7.0" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.15" level="project" />
<orderEntry type="library" name="Maven: org.beanshell:bsh:2.0b4" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-java:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-api:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-support:3.141.59" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.8.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:25.0-jre" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.0.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.11.0" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okio:okio:1.14.0" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:3.141.59" level="project" />
</component>
</module>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.testng:testng:6.9.9" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Maven: com.beust:jcommander:1.48" level="project" />
<orderEntry type="library" name="Maven: org.apache.ant:ant:1.7.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.7.0" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.15" level="project" />
<orderEntry type="library" name="Maven: org.beanshell:bsh:2.0b4" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-java:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-api:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-support:3.141.59" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.8.15" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:25.0-jre" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.0.0" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
<orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.11.0" level="project" />
<orderEntry type="library" name="Maven: com.squareup.okio:okio:1.14.0" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:3.141.59" level="project" />
<orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:3.141.59" level="project" />
</component>
</module>

29
pom.xml
View File

@@ -4,25 +4,26 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.agile611.trainings.webdriver</groupId>
<artifactId>cursoSeleniumWebdriver</artifactId>
<version>19.08.15</version>
<version>26.04.23</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<version>3.1.2</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/main/resources/suite.xml</suiteXmlFile>
<suiteXmlFile>src/test/resources/suite.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>8</source>
<target>8</target>
<source>25</source>
<target>25</target>
</configuration>
</plugin>
</plugins>
@@ -37,22 +38,32 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.9</version>
<version>7.10.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<version>4.43.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>3.141.59</version>
<version>4.43.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
<version>4.43.0</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>net.lightbody.bmp</groupId>
<artifactId>browsermob-core</artifactId>
<version>2.1.5</version>
</dependency>
</dependencies>
</project>

BIN
src/.DS_Store vendored

Binary file not shown.

BIN
src/main/.DS_Store vendored

Binary file not shown.

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.

View File

@@ -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>

View File

@@ -0,0 +1,68 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import java.time.Duration;
public class AlertsTest extends BaseTest {
public void acceptAlert() {
try {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
} catch (Exception e) {
//exception handling
}
}
public void dismissAlert() {
try {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.dismiss();
} catch (Exception e) {
//exception handling
}
}
public void promptAlert() {
try {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.sendKeys("Hola hola super hola");
alert.accept();
} catch (Exception e) {
//exception handling
}
}
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/javascript_alerts");
driver.findElement(By.xpath(".//*[@id='content']/div/ul/li[1]/button")).click();
Thread.sleep(2000);
acceptAlert();
Thread.sleep(2000);
driver.findElement(By.xpath(".//*[@id='content']/div/ul/li[2]/button")).click();
Thread.sleep(2000);
acceptAlert();
Thread.sleep(2000);
driver.findElement(By.xpath(".//*[@id='content']/div/ul/li[2]/button")).click();
Thread.sleep(2000);
dismissAlert();
Thread.sleep(2000);
driver.findElement(By.xpath(".//*[@id='content']/div/ul/li[3]/button")).click();
Thread.sleep(2000);
promptAlert();
Thread.sleep(2000);
}
}

View File

@@ -0,0 +1,44 @@
package com.agile611.testng.webdriver;
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
public class BaseRemoteWebDriverTest {
public RemoteWebDriver driver;
@BeforeClass(alwaysRun = true) //Inicialización del navegador
public void setUp() throws Exception {
String browser = System.getProperty("browser");
// Extraemos la URL para mantener el código DRY (Don't Repeat Yourself)
URL gridUrl = new URL("http://0.0.0.0:4444/wd/hub");
if (browser != null && browser.equalsIgnoreCase("chrome")) {
ChromeOptions options = new ChromeOptions();
driver = new RemoteWebDriver(gridUrl, options);
} else if (browser != null && browser.equalsIgnoreCase("safari")) {
SafariOptions options = new SafariOptions();
// Aquí podrías añadir configuraciones específicas si lo necesitas
// options.setUseTechnologyPreview(true);
driver = new RemoteWebDriver(gridUrl, options);
} else {
// Firefox se mantiene como el navegador por defecto (fallback)
FirefoxOptions options = new FirefoxOptions();
driver = new RemoteWebDriver(gridUrl, options);
}
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
}
@AfterClass(alwaysRun = true) //El cierre del navegador
public void tearDown() throws Exception {
driver.quit();
}
}

View File

@@ -0,0 +1,49 @@
package com.agile611.testng.webdriver;
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
public class BaseSaucelabsTest {
public RemoteWebDriver driver;
@BeforeClass(alwaysRun = true) //Inicialización del navegador
public void setUp() throws Exception {
String browser = System.getProperty("browser");
if (browser != null && browser.equalsIgnoreCase("chrome")) {
ChromeOptions options = new ChromeOptions();
driver = new RemoteWebDriver(new URL("http://selgp:ee557a77-606f-451d-9c8b-a4bb3ef03c90@ondemand.saucelabs.com:80/wd/hub"), options);
}
else if(browser != null && browser.equalsIgnoreCase("safari")) {
SafariOptions options = new SafariOptions();
driver = new RemoteWebDriver(new URL("http://selgp:ee557a77-606f-451d-9c8b-a4bb3ef03c90@ondemand.saucelabs.com:80/wd/hub"), options);
}
else if(browser != null && browser.equalsIgnoreCase("ie")) {
InternetExplorerOptions options = new InternetExplorerOptions();
driver = new RemoteWebDriver(new URL("http://selgp:ee557a77-606f-451d-9c8b-a4bb3ef03c90@ondemand.saucelabs.com:80/wd/hub"), options);
}
else if(browser != null && browser.equalsIgnoreCase("edge")) {
EdgeOptions options = new EdgeOptions();
options.setCapability("platform", "Windows 10");
options.setCapability("version", "15.15063");
driver = new RemoteWebDriver(new URL("http://selgp:ee557a77-606f-451d-9c8b-a4bb3ef03c90@ondemand.saucelabs.com:80/wd/hub"), options);
}
else {
FirefoxOptions options = new FirefoxOptions();
driver = new RemoteWebDriver(new URL("http://selgp:ee557a77-606f-451d-9c8b-a4bb3ef03c90@ondemand.saucelabs.com:80/wd/hub"), options);
}
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
}
@AfterClass(alwaysRun = true) //El cierre del navegador
public void tearDown() throws Exception {
driver.quit();
}
}

View File

@@ -0,0 +1,42 @@
package com.agile611.testng.webdriver;
import java.io.File;
import java.time.Duration;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
public class BaseTest {
public WebDriver driver;
public static JavascriptExecutor jse;
@BeforeClass(alwaysRun = true) //Inicialización del navegador
public void setUp() throws Exception {
String browser = System.getProperty("browser");
if (browser != null && browser.equalsIgnoreCase("firefox")) {
FirefoxOptions options = new FirefoxOptions();
System.setProperty("webdriver.gecko.driver",
"src" + File.separator + "test"
+ File.separator + "resources"
+ File.separator + "geckodriver-macos");
driver = new FirefoxDriver(options);
} else {
ChromeOptions options = new ChromeOptions();
System.setProperty("webdriver.chrome.driver", "src" + File.separator + "test" + File.separator + "resources" + File.separator + "chromedriver-macos");
driver = new ChromeDriver(options);
}
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(30));
jse = (JavascriptExecutor) driver;
}
@AfterClass(alwaysRun = true) //El cierre del navegador
public void tearDown() throws Exception {
driver.quit();
}
}

View File

@@ -0,0 +1,12 @@
package com.agile611.testng.webdriver;
import org.testng.annotations.Test;
public class BasicAuth extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://admin:admin@the-internet.herokuapp.com/basic_auth");
Thread.sleep(5000);
}
}

View File

@@ -0,0 +1,89 @@
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 org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.testng.Assert;
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 BrokenImages {
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() {
// 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");
// 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.");
}
}

View File

@@ -0,0 +1,24 @@
package com.agile611.testng.webdriver;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
public class ChallengingDomTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/challenging_dom");
List<WebElement> botons =
driver.findElements(
By.xpath(".//div[@class='example']/div/div/div[1]/a"));
for (int i = 0; i < botons.size(); i++) {
WebElement botonDeTurno =
driver.findElement(
By.xpath(".//div[@class='example']/div/div/div[1]/a[" + (i + 1) + "]"));
botonDeTurno.click();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class CheckBoxesTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
//1 Navegar hasta la página
driver.navigate().to("https://the-internet.herokuapp.com/checkboxes");
//2 Mirar que el checkbox2 está marcado
WebElement checkbox2 =
driver.findElement(By.xpath(".//*[@id='checkboxes']/input[2]"));
assertTrue(checkbox2.getAttribute("checked").equals("true"));
//2.1 Mirar el checkbox1 que NO está marcado
WebElement checkbox1 =
driver.findElement(By.xpath(".//*[@id='checkboxes']/input[1]"));
assertNull(checkbox1.getAttribute("checked"));
//3 Marcar checkbox1
checkbox1.click();
//4 Mirar que ha quedado marcado
assertTrue(checkbox1.getAttribute("checked").equals("true"));
}
}

View File

@@ -0,0 +1,22 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
public class DisappearingElementsTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/disappearing_elements");
for (int i = 0; i < 10; i++) {
System.out.println("Iteración: " + (i + 1));
WebElement elementsDelMenu =
driver.findElement(
By.xpath(".//*[@id='content']/div/ul/li[last()]"));
elementsDelMenu.click();
driver.navigate().back();
driver.navigate().refresh();
}
}
}

View File

@@ -0,0 +1,93 @@
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.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class DownloadTest extends BaseTest {
File folder;
@BeforeMethod
public void setUp() {
folder = new File("src" + File.separator + "test" + File.separator + "resources" + File.separator + UUID.randomUUID().toString());
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>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", downloadFilepath);
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs", chromePrefs);
options.setAcceptInsecureCerts(true);
//options.addArguments("--headless");
driver = new ChromeDriver(options);
//Firefox
// 1. Configurar el perfil de Firefox
/*FirefoxProfile profile = new FirefoxProfile();
System.setProperty("webdriver.gecko.driver",
"src" + File.separator + "test"
+ File.separator + "resources"
+ File.separator + "geckodriver-macos");
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.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", downloadFilepath);
// 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
public void tearDown() {
driver.quit();
}
@Test
public void download() throws Exception {
folder.mkdir();
driver.get("http://the-internet.herokuapp.com/download");
Thread.sleep(2000);
Actions actions = new Actions(driver);
WebElement link = driver.findElement(By.xpath("/html[1]/body[1]/div[2]/div[1]/div[1]/a[1]"));
actions.dragAndDrop(link, link).build().perform();
// Wait 2 seconds to download file
Thread.sleep(2000);
File[] listOfFiles = folder.listFiles();
// Make sure the directory is not empty
assertThat(listOfFiles.length, is(not(0)));
for (File file : listOfFiles) {
// Make sure the downloaded file(s) is(are) not empty
assertThat(file.length(), is(not((long) 0)));
}
String[] entries = folder.list();
for (String s : entries) {
File currentFile = new File(folder.getPath(), s);
currentFile.delete();
}
folder.delete();
}
}

View File

@@ -0,0 +1,46 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
public class DragAndDropJavascriptTest extends BaseTest {
@Test
public void testAppConJS() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/drag_and_drop");
Thread.sleep(2000);
WebElement columnA = driver.findElement(By.id("column-a"));
WebElement columnB = driver.findElement(By.id("column-b"));
// Script JS que simula los eventos HTML5 drag & drop correctamente
String script =
"function simulateDragDrop(sourceNode, destinationNode) {" +
" var EVENT_TYPES = ['dragstart','dragenter','dragover','drop','dragend'];" +
" function createEvent(eventType) {" +
" var event = document.createEvent('CustomEvent');" +
" event.initCustomEvent(eventType, true, true, null);" +
" event.dataTransfer = { data: {}, setData: function(type, val) { this.data[type]=val; }, getData: function(type) { return this.data[type]; } };" +
" return event;" +
" }" +
" var dragEvent = createEvent('dragstart');" +
" sourceNode.dispatchEvent(dragEvent);" +
" destinationNode.dispatchEvent(createEvent('dragenter'));" +
" destinationNode.dispatchEvent(createEvent('dragover'));" +
" var dropEvent = createEvent('drop');" +
" dropEvent.dataTransfer = dragEvent.dataTransfer;" +
" destinationNode.dispatchEvent(dropEvent);" +
" sourceNode.dispatchEvent(createEvent('dragend'));" +
"}" +
"simulateDragDrop(arguments[0], arguments[1]);";
((JavascriptExecutor) driver).executeScript(script, columnA, columnB);
Thread.sleep(2000);
// Verificar el intercambio
assertEquals(driver.findElement(By.cssSelector("#column-a header")).getText(), "B");
assertEquals(driver.findElement(By.cssSelector("#column-b header")).getText(), "A");
}
}

View File

@@ -0,0 +1,34 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
public class DragAndDropTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/drag_and_drop");
Thread.sleep(2000);
// Localizar los dos elementos con sus IDs reales
WebElement columnA = driver.findElement(By.id("column-a"));
WebElement columnB = driver.findElement(By.id("column-b"));
// Verificar estado inicial: A está a la izquierda, B a la derecha
assertEquals(columnA.findElement(By.tagName("header")).getText(), "A");
assertEquals(columnB.findElement(By.tagName("header")).getText(), "B");
// Arrastrar A sobre B (intercambiar posiciones)
Actions dragAndDrop = new Actions(driver);
dragAndDrop.dragAndDrop(columnA, columnB).perform();
Thread.sleep(2000);
// Verificar que han intercambiado: ahora A está donde estaba B y viceversa
assertEquals(columnA.findElement(By.tagName("header")).getText(), "B");
assertEquals(columnB.findElement(By.tagName("header")).getText(), "A");
}
}

View File

@@ -0,0 +1,27 @@
package com.agile611.testng.webdriver;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class DropdownTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver
.navigate().to("https://the-internet.herokuapp.com/dropdown");
List<WebElement> options =
driver.findElements(By.xpath(".//*[@id='dropdown']/option"));
for (int i = 1; i < options.size(); i++) {
WebElement option =
driver.findElement(
By.xpath(".//*[@id='dropdown']/option[" + (i + 1) + "]"));
option.click();
assertTrue(option.isSelected());
}
}
}

View File

@@ -0,0 +1,19 @@
package com.agile611.testng.webdriver;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
import com.agile611.testng.webdriver.pages.ResultsPage;
import com.agile611.testng.webdriver.pages.SearchPage;
public class DuckDuckGoPagesTest extends BaseTest {
@Test
public void testUntitledTestCase() throws Exception {
SearchPage searchPage = new SearchPage(driver);
searchPage.searchKeyword("pizza hawaiana");
ResultsPage resultsPage = new ResultsPage(driver);
assertTrue(resultsPage.isResultsPagePresent());
}
}

View File

@@ -1,3 +1,28 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class DuckDuckGoTest extends BaseTest {
@FindBy(id = "searchbox_input")
public WebElement searchBox;
@FindBy(className = "react-results--main")
public WebElement resultsList;
@Test
public void testSearch() throws Exception {
PageFactory.initElements(driver, this);
driver.get("https://duckduckgo.com/");
Thread.sleep(2000);
searchBox.sendKeys("pizza hawaiana");
searchBox.submit();
Thread.sleep(2000);
assertTrue(resultsList.isDisplayed());
}
}

View File

@@ -0,0 +1,34 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
import static org.testng.AssertJUnit.assertFalse;
public class DynamicContentTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/dynamic_content");
WebElement imatge1 =
driver.findElement(
By.xpath(".//*[@id='content']/div[3]/div[1]/img"));
WebElement text1 =
driver.findElement(
By.xpath(".//*[@id='content']/div[3]/div[2]"));
String urlImatge1 = imatge1.getAttribute("src");
String texttotal1 = text1.getText();
driver.navigate().refresh(); //Regenero el DOM completo
imatge1 =
driver.findElement(
By.xpath(".//*[@id='content']/div[3]/div[1]/img"));
text1 =
driver.findElement(
By.xpath(".//*[@id='content']/div[3]/div[2]"));
String urlImatge2 = imatge1.getAttribute("src");
String texttotal2 = text1.getText();
assertFalse(urlImatge1.equals(urlImatge2));
assertFalse(texttotal1.equals(texttotal2));
}
}

View File

@@ -0,0 +1,30 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import java.time.Duration;
import static org.testng.Assert.assertTrue;
public class DynamicControlsTest extends BaseTest {
@Test
public void titleTest() throws InterruptedException {
driver.navigate().to("http://the-internet.herokuapp.com/dynamic_controls");
WebElement checkbox = driver.findElement(By.id("checkbox"));
assertTrue(checkbox.isDisplayed());
checkbox.click();
WebElement removeBtn = driver.findElement(By.xpath("//*[@id='checkbox-example']/button"));
removeBtn.click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
wait.until(ExpectedConditions.or(
ExpectedConditions.presenceOfElementLocated(By.id("loading")),
ExpectedConditions.presenceOfElementLocated(By.id("message"))));
WebElement message = driver.findElement(By.id("message"));
assertTrue(message.isDisplayed());
}
}

View File

@@ -0,0 +1,34 @@
package com.agile611.testng.webdriver;
import java.time.Duration;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class HoversImprovedTest extends BaseTest {
@Test
public void hoversTest() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/hovers");
// Find and hover over desired element
List<WebElement> avatars = driver.findElements(By.xpath("//*[@id=\'content\']/div/div"));
for(int i= 1; i <= avatars.size(); i++){
WebElement avatar = driver.findElement(By.xpath("//*[@id=\'content\']/div/div["+i+"]/img"));
Actions builder = new Actions(driver);
builder.moveToElement(avatar).build().perform();
// Wait until the hover appears
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id=\'content\']/div/div["+i+"]/div/h5")));
// Assert that the hover displayed
assertTrue(driver.findElement(By.xpath("//*[@id=\'content\']/div/div["+i+"]/div/h5")).isDisplayed());
assertTrue(driver.findElement(By.xpath("//*[@id=\'content\']/div/div["+i+"]/div/h5")).getText().contains("name: user"+i));
}
}
}

View File

@@ -0,0 +1,33 @@
package com.agile611.testng.webdriver;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class HoversTest extends BaseTest {
@Test
public void hoversTest() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/hovers");
Thread.sleep(3000);
// Find and hover over desired element
WebElement avatar = driver.findElement(By.className("figure"));
Actions builder = new Actions(driver);
builder.moveToElement(avatar).build().perform();
Thread.sleep(3000);
// Wait until the hover appears
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("figcaption")));
Thread.sleep(3000);
// Assert that the hover displayed
assertTrue(driver.findElement(By.className("figcaption")).isDisplayed());
Thread.sleep(3000);
}
}

View File

@@ -0,0 +1,15 @@
package com.agile611.testng.webdriver;
import org.testng.annotations.Test;
public class InfiniteScrollTest extends BaseTest {
@Test
public void infiniteScrollTest() throws InterruptedException {
driver.navigate().to("http://the-internet.herokuapp.com/infinite_scroll");
for (int i = 0; i < 5; i++) {
System.out.println("Iteración: " + (i + 1));
jse.executeScript("window.scrollTo(0, document.body.scrollHeight);");
Thread.sleep(2500);
}
}
}

View File

@@ -0,0 +1,20 @@
package com.agile611.testng.webdriver;
import org.testng.annotations.Test;
public class InterrogationTest extends BaseTest {
@Test //Opciones de Navegación
public void testNavigation() throws Exception {
driver.get("https://www.duckduckgo.com/"); //Navegar hasta duckduckgo
System.out.println("---------------------");
System.out.println(driver.getPageSource());
System.out.println("---------------------");
System.out.println(driver.getTitle());
System.out.println("---------------------");
System.out.println(driver.getCurrentUrl());
System.out.println("---------------------");
}
}

View File

@@ -0,0 +1,26 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class KeyboardKeysTest extends BaseTest {
@Test
public void KeyboardKeysExample() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/key_presses");
Actions builder = new Actions(driver);
builder.sendKeys(Keys.SPACE).build().perform();
assertTrue(driver.findElement(By.id("result")).getText().equalsIgnoreCase("You entered: SPACE"));
builder.sendKeys(Keys.LEFT).build().perform();
assertTrue(driver.findElement(By.id("result")).getText().equalsIgnoreCase("You entered: LEFT"));
WebElement textBox = driver.findElement(By.id("target"));
textBox.click();
textBox.sendKeys("Hello World");
textBox.sendKeys(Keys.ESCAPE);
assertTrue(driver.findElement(By.id("result")).getText().equalsIgnoreCase("You entered: ESCAPE"));
}
}

View File

@@ -0,0 +1,41 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
public class LargeDeepDomTest extends BaseTest {
/**
* @param element element on the page that will be highlighted
* @param duration the time in second how much the element will be highlighted
*/
private void highlightElement(WebElement element, int duration) throws InterruptedException {
// Store original style so it can be reset later
String original_style = element.getAttribute("style");
// Style element with a red border
jse.executeScript(
"arguments[0].setAttribute(arguments[1], arguments[2])",
element,
"style",
"border: 2px solid red; border-style: dashed;");
// Keep element highlighted for a spell and then revert
if (duration > 0) {
Thread.sleep(duration * 1000);
jse.executeScript(
"arguments[0].setAttribute(arguments[1], arguments[2])",
element,
"style",
original_style);
}
}
@Test
public void highlightElementTest() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/large");
WebElement element = driver.findElement(By.id("sibling-2.3"));
highlightElement(element, 3);
}
}

View File

@@ -0,0 +1,13 @@
package com.agile611.testng.webdriver;
import org.testng.annotations.Test;
public class LoginTest extends BaseRemoteWebDriverTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://www.duckduckgo.com");
Thread.sleep(5000);
}
}

View File

@@ -0,0 +1,34 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
public class ManipulationTest extends BaseTest {
@Test //Opciones de Navegación
public void testNavigation() throws Exception {
driver.get("https://www.duckduckgo.com/"); //Navegar hasta duckduckgo
driver.findElement(By.id("searchbox_input")).clear(); //Limpiar el text box
driver.findElement(By.id("searchbox_input")).sendKeys("pizza hawaiana"); //Escribir en el text box
driver.findElement(By.id("searchbox_input")).submit(); //Submit, darle al enter.
Thread.sleep(2000); //Espera forzada
WebElement resultsList = driver.findElement(By.className("react-results--main")); //Comprobar que el resultado se muestra
assertTrue(resultsList.isDisplayed());
driver.get("https://www.duckduckgo.com/"); //Navegar hasta duckduckgo
driver.findElement(By.id("searchbox_input")).clear(); //Limpiar el text box
driver.findElement(By.id("searchbox_input")).sendKeys("tortellini al pesto");
Thread.sleep(2000); //Espera forzada
Actions builder = new Actions(driver);
WebElement searchButton = driver.findElement(By.xpath(".//button[@data-mode=\'search\']")); //Click en el text box, no hace nada pero es para mostrar la diferencia entre submit y click.
builder.moveToElement(searchButton).click().build().perform(); //Click en el botón de búsqueda, esto es diferente a submit, ya que submit solo funciona con formularios, mientras que click funciona con cualquier elemento.
Thread.sleep(2000); //Espera forzada
resultsList = driver.findElement(By.className("react-results--main")); //Comprobar que el resultado se muestra
assertTrue(resultsList.isDisplayed());
}
}

View 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");
}
}
}

View File

@@ -0,0 +1,84 @@
package com.agile611.testng.webdriver;
import java.time.Duration;
import java.util.Set;
import static org.hamcrest.CoreMatchers.equalTo;
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.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
public class MultipleWindowsTest extends BaseTest {
@Test
public void multipleWindows() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/windows");
String originalWindow = driver.getWindowHandle();
driver.findElement(By.xpath("//a[@href=\'/windows/new\']")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
Thread.sleep(3000); // Temas del Firefox
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
// numberOfWindowsToBe de Firefox no se interpreta bien, por eso el sleep
String newWindow = "";
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(originalWindow)) {
newWindow = handle;
}
}
// Verificar ventana original
driver.switchTo().window(originalWindow);
assertThat(driver.getTitle(), is(not(equalTo("New Window"))));
// Verificar nueva ventana
driver.switchTo().window(newWindow);
assertThat(driver.getTitle(), is(equalTo("New Window")));
// ✅ Cerrar la ventana nueva y volver a la original
driver.close();
driver.switchTo().window(originalWindow);
}
@Test(dependsOnMethods = "multipleWindows")
public void multipleWindowsRedux() throws InterruptedException {
driver.get("http://the-internet.herokuapp.com/windows");
String firstWindow = driver.getWindowHandle();
String newWindow = "";
driver.findElement(By.cssSelector(".example a")).click();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
Thread.sleep(3000); // Temas de tiempos del Firefox
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
// numberOfWindowsToBe de Firefox no se interpreta bien, por eso el sleep
Set<String> allWindows = driver.getWindowHandles();
for (String window : allWindows) {
if (!window.equals(firstWindow)) {
newWindow = window;
}
}
driver.switchTo().window(firstWindow);
assertThat(driver.getTitle(), is(not(equalTo("New Window"))));
driver.switchTo().window(newWindow);
assertThat(driver.getTitle(), is(equalTo("New Window")));
// ✅ Cerrar la ventana nueva y volver a la original
driver.close();
driver.switchTo().window(firstWindow);
}
}

View File

@@ -0,0 +1,21 @@
package com.agile611.testng.webdriver;
import org.testng.annotations.Test;
public class NavigationTest extends BaseTest {
@Test //Opciones de Navegación
public void testNavigation() throws Exception {
driver.get("https://www.duckduckgo.com/"); //Navegar hasta duckduckgo
Thread.sleep(2000);
driver.navigate().to("https://www.google.com"); //Navegar hasta Google
Thread.sleep(2000);
driver.get("https://www.yahoo.com"); //Navegar hasta Yahoo
Thread.sleep(2000);
driver.navigate().back(); //Hacia atrás (Volver a Google)
Thread.sleep(2000);
driver.navigate().forward(); //Hacia adelante (Volver a Yahoo)
Thread.sleep(2000);
driver.navigate().refresh(); //Refrescar Yahoo
Thread.sleep(2000);
}
}

View File

@@ -0,0 +1,32 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
import java.util.List;
public class NestedFramesTest extends BaseTest {
public void listIframesFromPage(WebDriver driver) {
final List<WebElement> iframes = driver.findElements(By.tagName("frame"));
for (WebElement iframe : iframes) {
System.out.println(iframe.getAttribute("id"));
System.out.println(iframe.getAttribute("name"));
}
}
@Test
public void testApp() {
driver.navigate().to("https://the-internet.herokuapp.com/nested_frames");
listIframesFromPage(driver);
driver.switchTo().frame("frame-bottom");
System.out.println(driver.findElement(By.xpath("html/body")).getText());
driver.switchTo().defaultContent();
driver.switchTo().frame("frame-top");
listIframesFromPage(driver);
driver.switchTo().frame("frame-middle");
System.out.println(driver.findElement(By.xpath("html/body")).getText());
}
}

View File

@@ -0,0 +1,170 @@
package com.agile611.testng.webdriver;
import java.io.File;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
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 {
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 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");
// 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
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");
// 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
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");
// 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
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");
// 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.");
}
}

View File

@@ -0,0 +1,27 @@
package com.agile611.testng.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
public class TestABTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
int counter1=0, counter2=0;
for(int i=0; i < 1000; i++){
driver.get("https://the-internet.herokuapp.com/abtest");
WebElement title =
driver.findElement(By.xpath(".//*[@id='content']/div/h3"));
if(title.getText().equals("A/B Test Variation 1")){
counter1++;
}
else{
counter2++;
}
driver.manage().deleteAllCookies();
}
System.out.println("He recibido la version 1 "+counter1);
System.out.println("He recibido la version 2 "+counter2);
}
}

View File

@@ -0,0 +1,30 @@
package com.agile611.testng.webdriver;
import java.io.File;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import static org.testng.AssertJUnit.assertTrue;
import org.testng.annotations.Test;
public class UploadTest extends BaseTest {
@Test
public void testApp() throws InterruptedException {
driver.navigate().to("https://the-internet.herokuapp.com/upload");
WebElement fileUpload = driver.findElement(By.id("file-upload"));
File file = new File("src" + File.separator + "test"
+ File.separator + "resources" + File.separator + "2-logo-B_activa.png");
fileUpload.sendKeys(file.getAbsolutePath());
WebElement buttonUpload = driver.findElement(By.id("file-submit"));
buttonUpload.click();
WebElement uploadedFiles = driver.findElement(By.id("uploaded-files"));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
wait.until(ExpectedConditions.visibilityOf(uploadedFiles));
assertTrue(uploadedFiles.isDisplayed());
}
}

View File

@@ -0,0 +1,23 @@
package com.agile611.testng.webdriver.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class ResultsPage {
private WebDriver driver;
@FindBy(className = "react-results--main")
public WebElement resultsList;
public ResultsPage(WebDriver driver) {
PageFactory.initElements(driver, this);
}
public boolean isResultsPagePresent() {
return resultsList.isDisplayed();
}
}

View File

@@ -0,0 +1,25 @@
package com.agile611.testng.webdriver.pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class SearchPage {
private WebDriver driver;
@FindBy(id = "searchbox_input")
public WebElement searchBox;
public SearchPage(WebDriver driver) {
PageFactory.initElements(driver, this);
driver.get("https://duckduckgo.com/");
}
public void searchKeyword(String keyword) {
searchBox.clear();
searchBox.sendKeys(keyword);
searchBox.submit();
}
}

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

Binary file not shown.