Implement HW5 stubs, API helpers, optional SQL/MQ helpers, and test coverage

This commit is contained in:
2026-03-09 01:40:48 +03:00
parent d1247eec18
commit 507e14bc2e
53 changed files with 2320 additions and 56 deletions

View File

@@ -0,0 +1,27 @@
package ru.kovbasa.elements;
import org.openqa.selenium.WebElement;
public abstract class BaseElement implements UIElement {
protected final WebElement element;
protected BaseElement(WebElement element) {
this.element = element;
}
@Override
public void click() {
element.click();
}
@Override
public String getText() {
return element.getText();
}
@Override
public boolean isDisplayed() {
return element.isDisplayed();
}
}

View File

@@ -0,0 +1,14 @@
package ru.kovbasa.elements;
import org.openqa.selenium.WebElement;
public class Button extends BaseElement {
public Button(WebElement element) {
super(element);
}
public boolean isEnabled() {
return element.isEnabled();
}
}

View File

@@ -0,0 +1,77 @@
package ru.kovbasa.elements;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CourseCard extends BaseElement {
private final By titleLocator = By.cssSelector("h6 .sc-hrqzy3-1");
private final By dateLocator = By.cssSelector(".sc-157icee-1 .sc-hrqzy3-1");
private static final Pattern PRICE_PATTERN = Pattern.compile("(\\d[\\d\\s]*)\\s*[₽р]");
public CourseCard(WebElement element) {
super(element);
}
public String title() {
return element.findElement(titleLocator).getText().trim();
}
public LocalDate startDate() {
String raw = element.findElement(dateLocator).getText().trim();
if (raw.isEmpty()) {
throw new RuntimeException("Пустая дата на карточке курса: " + title());
}
String[] parts = raw.split("·");
String datePart = parts[0].trim();
if (datePart.startsWith("С ")) {
datePart = datePart.substring(2).trim();
}
datePart = datePart.replace(",", "").replace("года", "").trim();
boolean hasYear = datePart.matches(".*\\d{4}.*");
String normalized;
DateTimeFormatter formatter;
if (hasYear) {
normalized = datePart;
formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.forLanguageTag("ru"));
} else {
normalized = datePart + " " + Year.now().getValue();
formatter = DateTimeFormatter.ofPattern("d MMMM yyyy", Locale.forLanguageTag("ru"));
}
return LocalDate.parse(normalized, formatter);
}
public int price() {
final String text = element.getText();
final Matcher matcher = PRICE_PATTERN.matcher(text);
int maxPrice = -1;
while (matcher.find()) {
final String raw = matcher.group(1).replace(" ", "");
final int parsed = Integer.parseInt(raw);
if (parsed > maxPrice) {
maxPrice = parsed;
}
}
if (maxPrice < 0) {
throw new RuntimeException("Цена курса не найдена в карточке: " + title());
}
return maxPrice;
}
}

View File

@@ -0,0 +1,14 @@
package ru.kovbasa.elements;
import org.openqa.selenium.WebElement;
public class Link extends BaseElement {
public Link(WebElement element) {
super(element);
}
public String getHref() {
return element.getAttribute("href");
}
}

View File

@@ -0,0 +1,7 @@
package ru.kovbasa.elements;
public interface UIElement {
void click();
String getText();
boolean isDisplayed();
}