Best Testcontainers-java code snippet using org.testcontainers.hivemq.HiveMQContainer.cloneWithFileMode
Source:HiveMQContainer.java
...212 }213 try {214 final String extensionDirName = getExtensionDirectoryName(extensionDir);215 final String containerPath = "/opt/hivemq/temp-extensions/" + extensionDirName;216 withCopyFileToContainer(cloneWithFileMode(mountableExtension), containerPath);217 LOGGER.info("Putting extension '{}' into '{}'", extensionDirName, containerPath);218 } catch (final Exception e) {219 throw new ContainerLaunchException(e.getMessage() == null ? "" : e.getMessage(), e);220 }221 return self();222 }223 private @NotNull String getExtensionDirectoryName(final @NotNull File extensionDirectory) throws IOException {224 final File file = new File(extensionDirectory, "hivemq-extension.xml");225 final String xml = FileUtils.readFileToString(file, StandardCharsets.UTF_8);226 final Matcher matcher = EXTENSION_ID_PATTERN.matcher(xml);227 if (!matcher.find()) {228 throw new IllegalStateException("Could not parse extension id from '" + file.getAbsolutePath() + "'");229 }230 return matcher.group(1);231 }232 /**233 * Removes the specified prepackaged extension folders from '/opt/hivemq/extensions' before the container is started.234 * <p>235 * Must be called before the container is started.236 *237 * @param extensionIds the prepackaged extensions to remove238 * @return self239 */240 public @NotNull HiveMQContainer withoutPrepackagedExtensions(final @NotNull String... extensionIds) {241 Collections.addAll(prepackagedExtensionsToRemove, extensionIds);242 return self();243 }244 /**245 * Removes all prepackaged extension folders from '/opt/hivemq/extensions' before the container is started.246 * <p>247 * Must be called before the container is started.248 *249 * @return self250 */251 public @NotNull HiveMQContainer withoutPrepackagedExtensions() {252 removeAllPrepackagedExtensions = true;253 return self();254 }255 /**256 * Puts the given license into '/opt/hivemq/license/' inside the container.257 * It must end with '.lic' or '.elic'.258 * <p>259 * Must be called before the container is started.260 *261 * @param mountableLicense the license file on the host machine262 * @return self263 */264 public @NotNull HiveMQContainer withLicense(final @NotNull MountableFile mountableLicense) {265 final File licenseFile = new File(mountableLicense.getResolvedPath());266 if (!licenseFile.exists()) {267 throw new ContainerLaunchException(268 "License file '" + mountableLicense.getFilesystemPath() + "' does not exist."269 );270 }271 if (!licenseFile.getName().endsWith(".lic") && !licenseFile.getName().endsWith(".elic")) {272 throw new ContainerLaunchException(273 "License file '" + mountableLicense.getFilesystemPath() + "' does not end wit '.lic' or '.elic'."274 );275 }276 final String containerPath = "/opt/hivemq/license/" + licenseFile.getName();277 withCopyFileToContainer(cloneWithFileMode(mountableLicense), containerPath);278 LOGGER.info("Putting license '{}' into '{}'.", licenseFile.getAbsolutePath(), containerPath);279 return self();280 }281 /**282 * Overwrites the HiveMQ configuration in '/opt/hivemq/conf/' inside the container.283 * <p>284 * Must be called before the container is started.285 *286 * @param mountableConfig the config file on the host machine287 * @return self288 */289 public @NotNull HiveMQContainer withHiveMQConfig(final @NotNull MountableFile mountableConfig) {290 final File config = new File(mountableConfig.getResolvedPath());291 if (!config.exists()) {292 throw new ContainerLaunchException(293 "HiveMQ config file '" + mountableConfig.getFilesystemPath() + "' does not exist."294 );295 }296 final String containerPath = "/opt/hivemq/conf/config.xml";297 withCopyFileToContainer(cloneWithFileMode(mountableConfig), containerPath);298 LOGGER.info("Putting '{}' into '{}'.", config.getAbsolutePath(), containerPath);299 return self();300 }301 /**302 * Puts the given file into the root of the extension's home '/opt/hivemq/temp-extensions/{extensionId}/'.303 * <p>304 * Must be called before the container is started.305 * <p>306 * The contents of the '/opt/hivemq/temp-extensions/' directory are copied to '/opt/hivemq/extensions/' before the container is started.307 *308 * @param file the file on the host machine309 * @param extensionId the extension310 * @return self311 */312 public @NotNull HiveMQContainer withFileInExtensionHomeFolder(313 final @NotNull MountableFile file,314 final @NotNull String extensionId315 ) {316 return withFileInExtensionHomeFolder(file, extensionId, "");317 }318 /**319 * Puts the given file into given subdirectory of the extensions's home '/opt/hivemq/temp-extensions/{id}/{pathInExtensionHome}/'320 * <p>321 * Must be called before the container is started.322 * <p>323 * The contents of the '/opt/hivemq/temp-extensions/' directory are copied to '/opt/hivemq/extensions/' before the container is started.324 *325 * @param file the file on the host machine326 * @param extensionId the extension327 * @param pathInExtensionHome the path328 * @return self329 */330 public @NotNull HiveMQContainer withFileInExtensionHomeFolder(331 final @NotNull MountableFile file,332 final @NotNull String extensionId,333 final @NotNull String pathInExtensionHome334 ) {335 return withFileInHomeFolder(336 file,337 "/temp-extensions/" + extensionId + PathUtil.prepareAppendPath(pathInExtensionHome)338 );339 }340 /**341 * Puts the given file into the given subdirectory of the HiveMQ home folder '/opt/hivemq/{pathInHomeFolder}'.342 * <p>343 * Must be called before the container is started.344 *345 * @param mountableFile the file on the host machine346 * @param pathInHomeFolder the path347 * @return self348 */349 public @NotNull HiveMQContainer withFileInHomeFolder(350 final @NotNull MountableFile mountableFile,351 final @NotNull String pathInHomeFolder352 ) {353 final File file = new File(mountableFile.getResolvedPath());354 if (pathInHomeFolder.trim().isEmpty()) {355 throw new ContainerLaunchException("pathInHomeFolder must not be empty");356 }357 if (!file.exists()) {358 throw new ContainerLaunchException("File '" + mountableFile.getFilesystemPath() + "' does not exist.");359 }360 final String containerPath = "/opt/hivemq" + PathUtil.prepareAppendPath(pathInHomeFolder);361 withCopyFileToContainer(cloneWithFileMode(mountableFile), containerPath);362 LOGGER.info("Putting file '{}' into container path '{}'.", file.getAbsolutePath(), containerPath);363 return self();364 }365 /**366 * Disables the extension with the given name and extension directory name.367 * This method blocks until the HiveMQ log for successful disabling is consumed or it times out after {timeOut}.368 * Note: Disabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.369 * <p>370 * This can only be called once the container is started.371 *372 * @param extensionName the name of the extension to disable373 * @param extensionDirectory the name of the extension's directory374 * @param timeout the timeout375 * @throws TimeoutException if the extension was not disabled within the configured timeout376 */377 public void disableExtension(378 final @NotNull String extensionName,379 final @NotNull String extensionDirectory,380 final @NotNull Duration timeout381 ) throws TimeoutException {382 final String regEX = "(.*)Extension \"" + extensionName + "\" version (.*) stopped successfully(.*)";383 try {384 final String containerPath =385 "/opt/hivemq/extensions" + PathUtil.prepareInnerPath(extensionDirectory) + "DISABLED";386 final CountDownLatch latch = new CountDownLatch(1);387 containerOutputLatches.put(regEX, latch);388 execInContainer("touch", containerPath);389 LOGGER.info("Putting DISABLED file into container path '{}'", containerPath);390 final boolean await = latch.await(timeout.getSeconds(), TimeUnit.SECONDS);391 if (!await) {392 throw new TimeoutException(393 "Extension disabling timed out after '" +394 timeout.getSeconds() +395 "' seconds. " +396 "Maybe you are using a HiveMQ Community Edition image, " +397 "which does not support disabling of extensions"398 );399 }400 } catch (final InterruptedException | IOException e) {401 throw new RuntimeException(e);402 } finally {403 containerOutputLatches.remove(regEX);404 }405 }406 /**407 * Disables the extension with the given name and extension directory name.408 * This method blocks until the HiveMQ log for successful disabling is consumed or it times out after 60 seconds.409 * Note: Disabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.410 * <p>411 * This can only be called once the container is started.412 *413 * @param extensionName the name of the extension to disable414 * @param extensionDirectory the name of the extension's directory415 * @throws TimeoutException if the extension was not disabled within 60 seconds416 */417 public void disableExtension(final @NotNull String extensionName, final @NotNull String extensionDirectory)418 throws TimeoutException {419 disableExtension(extensionName, extensionDirectory, Duration.ofSeconds(60));420 }421 /**422 * Disables the extension.423 * This method blocks until the HiveMQ log for successful disabling is consumed or it times out after {timeOut}.424 * Note: Disabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.425 * <p>426 * This can only be called once the container is started.427 *428 * @param hiveMQExtension the extension429 * @param timeout the timeout430 * @throws TimeoutException if the extension was not disabled within the configured timeout431 */432 public void disableExtension(final @NotNull HiveMQExtension hiveMQExtension, final @NotNull Duration timeout)433 throws TimeoutException {434 disableExtension(hiveMQExtension.getName(), hiveMQExtension.getId(), timeout);435 }436 /**437 * Disables the extension.438 * This method blocks until the HiveMQ log for successful disabling is consumed or it times out after 60 seconds.439 * Note: Disabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.440 * <p>441 * This can only be called once the container is started.442 *443 * @param hiveMQExtension the extension444 * @throws TimeoutException if the extension was not disabled within 60 seconds445 */446 public void disableExtension(final @NotNull HiveMQExtension hiveMQExtension) throws TimeoutException {447 disableExtension(hiveMQExtension, Duration.ofSeconds(60));448 }449 /**450 * Enables the extension with the given name and extension directory name.451 * This method blocks until the HiveMQ log for successful enabling is consumed or it times out after {timeOut}.452 * Note: Enabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.453 * <p>454 * This can only be called once the container is started.455 *456 * @param extensionName the name of the extension to disable457 * @param extensionDirectory the name of the extension's directory458 * @param timeout the timeout459 * @throws TimeoutException if the extension was not enabled within the configured timeout460 */461 public void enableExtension(462 final @NotNull String extensionName,463 final @NotNull String extensionDirectory,464 final @NotNull Duration timeout465 ) throws TimeoutException {466 final String regEX = "(.*)Extension \"" + extensionName + "\" version (.*) started successfully(.*)";467 try {468 final String containerPath =469 "/opt/hivemq/extensions" + PathUtil.prepareInnerPath(extensionDirectory) + "DISABLED";470 final CountDownLatch latch = new CountDownLatch(1);471 containerOutputLatches.put(regEX, latch);472 execInContainer("rm", "-rf", containerPath);473 LOGGER.info("Removing DISABLED file in container path '{}'", containerPath);474 final boolean await = latch.await(timeout.getSeconds(), TimeUnit.SECONDS);475 if (!await) {476 throw new TimeoutException(477 "Extension enabling timed out after '" +478 timeout.getSeconds() +479 "' seconds. " +480 "Maybe you are using a HiveMQ Community Edition image, " +481 "which does not support disabling of extensions"482 );483 }484 } catch (final InterruptedException | IOException e) {485 throw new RuntimeException(e);486 } finally {487 containerOutputLatches.remove(regEX);488 }489 }490 /**491 * Enables the extension with the given name and extension directory name.492 * This method blocks until the HiveMQ log for successful enabling is consumed or it times out after 60 seconds.493 * Note: Enabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.494 * <p>495 * This can only be called once the container is started.496 *497 * @param extensionName the name of the extension to disable498 * @param extensionDirectory the name of the extension's directory499 * @throws TimeoutException if the extension was not enabled within 60 seconds500 */501 public void enableExtension(final @NotNull String extensionName, final @NotNull String extensionDirectory)502 throws TimeoutException {503 enableExtension(extensionName, extensionDirectory, Duration.ofSeconds(60));504 }505 /**506 * Enables the extension.507 * This method blocks until the HiveMQ log for successful enabling is consumed or it times out after {timeOut}.508 * Note: Enabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.509 * <p>510 * This can only be called once the container is started.511 *512 * @param hiveMQExtension the extension513 * @param timeout the timeout514 * @throws TimeoutException if the extension was not enabled within the configured timeout515 */516 public void enableExtension(final @NotNull HiveMQExtension hiveMQExtension, final @NotNull Duration timeout)517 throws TimeoutException {518 enableExtension(hiveMQExtension.getName(), hiveMQExtension.getId(), timeout);519 }520 /**521 * Enables the extension.522 * This method blocks until the HiveMQ log for successful enabling is consumed or it times out after {timeOut}.523 * Note: Enabling Extensions is a HiveMQ Enterprise feature, it will not work when using the HiveMQ Community Edition.524 * <p>525 * This can only be called once the container is started.526 *527 * @param hiveMQExtension the extension528 * @throws TimeoutException if the extension was not enabled within 60 seconds529 */530 public void enableExtension(final @NotNull HiveMQExtension hiveMQExtension) throws TimeoutException {531 enableExtension(hiveMQExtension, Duration.ofSeconds(60));532 }533 /**534 * Enables connection to the HiveMQ Control Center on host port 8080.535 * Note: the control center is a HiveMQ 4 Enterprise feature.536 * <p>537 * Must be called before the container is started.538 *539 * @return self540 */541 public @NotNull HiveMQContainer withControlCenter() {542 addExposedPorts(CONTROL_CENTER_PORT);543 controlCenterEnabled = true;544 return self();545 }546 /**547 * Get the mapped port for the MQTT port of the container.548 * <p>549 * Must be called after the container is started.550 *551 * @return the port on the host machine for mqtt clients to connect552 */553 public int getMqttPort() {554 return this.getMappedPort(MQTT_PORT);555 }556 private @NotNull MountableFile cloneWithFileMode(final @NotNull MountableFile mountableFile) {557 return MountableFile.forHostPath(mountableFile.getResolvedPath(), HiveMQContainer.MODE);558 }559}...
cloneWithFileMode
Using AI Code Generation
1import org.testcontainers.hivemq.HiveMQContainer2import org.testcontainers.utility.MountableFile3def hiveMQContainer = new HiveMQContainer()4hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("config.xml"), "/opt/hivemq/conf/config.xml")5hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("extensions.xml"), "/opt/hivemq/conf/extensions.xml")6hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("logback.xml"), "/opt/hivemq/conf/logback.xml")7hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-license.txt"), "/opt/hivemq/conf/hivemq-license.txt")8hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-id.txt"), "/opt/hivemq/conf/hivemq-id.txt")9hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("entrypoint.sh"), "/opt/hivemq/bin/entrypoint.sh", 755)10hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("start.sh"), "/opt/hivemq/bin/start.sh", 755)11hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("stop.sh"), "/opt/hivemq/bin/stop.sh", 755)12hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("wait-for-it.sh"), "/opt/hivemq/bin/wait-for-it.sh", 755)13hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("log4j2.xml"), "/opt/hivemq/log4j2.xml")14hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-mqtt-websocket-client.js"), "/opt/hivemq/hivemq-mqtt-websocket-client.js")15hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-mqtt-websocket-client.min.js"), "/opt/hivemq/hivemq-mqtt-websocket-client.min.js")16hiveMQContainer.withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-mqtt-websocket-client.min.js.map"),
cloneWithFileMode
Using AI Code Generation
1import org.testcontainers.containers.output.Slf4jLogConsumer2import org.testcontainers.hivemq.HiveMQContainer3import org.testcontainers.utility.MountableFile4def hiveMQ = new HiveMQContainer()5 .withLogConsumer(new Slf4jLogConsumer(logger))6 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq.conf"), "/opt/hivemq/conf/hivemq.conf")7 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-internal.conf"), "/opt/hivemq/conf/hivemq-internal.conf")8 .withCopyFileToContainer(MountableFile.forClasspathResource("logback.xml"), "/opt/hivemq/conf/logback.xml")9 .withCopyFileToContainer(MountableFile.forClasspathResource("extensions"), "/opt/hivemq/extensions")10 .withCopyFileToContainer(MountableFile.forClasspathResource("certs"), "/opt/hivemq/certs")11 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-keystore.jks"), "/opt/hivemq/certs/hivemq-keystore.jks")12 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-truststore.jks"), "/opt/hivemq/certs/hivemq-truststore.jks")13 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-extension.jar"), "/opt/hivemq/extensions/hivemq-extension.jar", 500)14 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-extension2.jar"), "/opt/hivemq/extensions/hivemq-extension2.jar", 500)15 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-extension3.jar"), "/opt/hivemq/extensions/hivemq-extension3.jar", 500)16 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-extension4.jar"), "/opt/hivemq/extensions/hivemq-extension4.jar", 500)17 .withCopyFileToContainer(MountableFile.forClasspathResource("hivemq-extension5.jar"), "/opt
cloneWithFileMode
Using AI Code Generation
1import org.testcontainers.containers.output.Slf4jLogConsumer;2import org.testcontainers.hivemq.HiveMQContainer;3import org.testcontainers.hivemq.HiveMQTestContainerExtension;4import org.testcontainers.junit.jupiter.Container;5import org.testcontainers.junit.jupiter.Testcontainers;6import org.testcontainers.utility.MountableFile;7import org.junit.jupiter.api.Test;8import org.junit.jupiter.api.extension.RegisterExtension;9import java.nio.file.Paths;10import static org.junit.jupiter.api.Assertions.assertTrue;11public class HiveMQContainerCloneWithFileModeTest {12 static HiveMQTestContainerExtension hiveMQContainerExtension = new HiveMQTestContainerExtension();13 .withLogConsumer(new Slf4jLogConsumer(HiveMQContainerCloneWithFileModeTest.class))14 .withCopyFileToContainer(MountableFile.forHostPath(Paths.get("src/test/resources/hivemq-configuration.properties")),15 .cloneWithFileMode(0644, "/opt/hivemq/conf/hivemq-configuration.properties");16 public void test() {17 assertTrue(hiveMQContainer.isRunning());18 }19}
cloneWithFileMode
Using AI Code Generation
1public class HiveMQContainerTest extends AbstractContainerBaseTest {2 public void testSimple() {3 try (HiveMQContainer hivemq = new HiveMQContainer()) {4 hivemq.start();5 String containerIpAddress = hivemq.getContainerIpAddress();6 Integer mappedPort = hivemq.getMappedPort(1883);7 String mqttHostAndPort = containerIpAddress + ":" + mappedPort;8 System.out.println("mqttHostAndPort = " + mqttHostAndPort);9 MqttClient mqttClient = new MqttClient(mqttUrl, MqttClient.generateClientId());10 MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();11 mqttConnectOptions.setCleanSession(true);12 mqttClient.connect(mqttConnectOptions);13 MqttMessage mqttMessage = new MqttMessage();14 mqttMessage.setPayload("Hello, World!".getBytes());15 mqttClient.publish("topic", mqttMessage);16 mqttClient.disconnect();17 } catch (Exception e) {18 log.error("", e);19 }20 }21 public void testWithCustomConfiguration() {22 try (HiveMQContainer hivemq = new HiveMQContainer()23 .withConfigurationFileMode(0644)) {24 hivemq.start();25 String containerIpAddress = hivemq.getContainerIpAddress();26 Integer mappedPort = hivemq.getMappedPort(1883);27 String mqttHostAndPort = containerIpAddress + ":" + mappedPort;28 System.out.println("mqttHostAndPort = " + mqttHostAndPort);29 MqttClient mqttClient = new MqttClient(mqttUrl, MqttClient.generateClientId());30 MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();31 mqttConnectOptions.setCleanSession(true);32 mqttClient.connect(mqttConnectOptions);33 MqttMessage mqttMessage = new MqttMessage();34 mqttMessage.setPayload("Hello, World!".getBytes());35 mqttClient.publish("topic", mqttMessage);36 mqttClient.disconnect();37 } catch
cloneWithFileMode
Using AI Code Generation
1HiveMQContainer hivemq = new HiveMQContainer()2hivemq.cloneWithFileMode("/path/to/file", 600)3HiveMQContainer hivemq = new HiveMQContainer()4hivemq.withFileMode("/path/to/file", 600)5HiveMQContainer hivemq = new HiveMQContainer()6hivemq.withFileMode("/path/to/directory", 700)7HiveMQContainer hivemq = new HiveMQContainer()8hivemq.withFileMode("/path/to/directory", 700, true)9HiveMQContainer hivemq = new HiveMQContainer()10hivemq.withFileMode("/path/to/directory", 700, true)11 .withFileMode("/path/to/file", 600)12HiveMQContainer hivemq = new HiveMQContainer()13hivemq.withFileMode("/path/to/directory", 700, true)14 .withFileMode("/path/to/file", 600)15HiveMQContainer hivemq = new HiveMQContainer()16hivemq.withFileMode("/path/to/directory", 700, true)17 .withFileMode("/path/to/file", 600)18HiveMQContainer hivemq = new HiveMQContainer()19hivemq.withFileMode("/path/to/directory", 700, true)20 .withFileMode("/path/to/file", 600)21HiveMQContainer hivemq = new HiveMQContainer()
cloneWithFileMode
Using AI Code Generation
1import org.testcontainers.containers.GenericContainer;2import org.testcontainers.containers.wait.strategy.Wait;3import org.testcontainers.hivemq.HiveMQContainer;4import java.io.File;5import java.io.IOException;6import java.nio.file.Files;7import java.nio.file.Path;8import java.nio.file.Paths;9import java.nio.file.attribute.PosixFilePermission;10import java.util.Set;11public class HiveMQContainerExample {12 public static void main(String[] args) throws IOException {13 Path tempDirectory = Files.createTempDirectory("hivemq");14 Path tempFile = Paths.get(tempDirectory.toString(), "test.txt");15 Files.write(tempFile, "Hello World".getBytes());16 Set<PosixFilePermission> fileMode = Files.getPosixFilePermissions(tempFile);17 HiveMQContainer container = new HiveMQContainer()18 .withCopyFileToContainer(MountableFile.forHostPath(tempFile), "/opt/hivemq/test.txt")19 .cloneWithFileMode("/opt/hivemq/test.txt", fileMode);20 container.start();21 System.out.println("HiveMQ is running");22 }23}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!