Исправления: только официальный SMS-Activate, обновления proxy и генератора
This commit is contained in:
@ -512,16 +512,17 @@ public class GoogleAccountGeneratorImpl implements GoogleAccountGenerator
|
|||||||
if (useProxy && proxyManager.hasProxies())
|
if (useProxy && proxyManager.hasProxies())
|
||||||
{
|
{
|
||||||
chosenProxy = proxyManager.getNextProxy();
|
chosenProxy = proxyManager.getNextProxy();
|
||||||
// Парсим логин и пароль (login:pass@host:port)
|
if (chosenProxy == null) {
|
||||||
// HTTP(S)-прокси с Basic Auth
|
logger.error("Не удалось получить ни одного подходящего прокси с proxy6.net. Проверьте фильтры IP/тип или наличие активных прокси.");
|
||||||
String proxyUri = (proxyLogin + ":" + proxyPass + "@") + chosenProxy;
|
throw new RuntimeException("Нет доступных прокси для использования. Проверьте настройки proxy6.net и фильтры в ProxyManager.");
|
||||||
String scheme = chosenProxy.startsWith("http") ? "" : "http://";
|
}
|
||||||
String finalProxy = "--proxy-server=" + scheme + chosenProxy;
|
// Используем только host:port без логина и пароля
|
||||||
|
String finalProxy = "--proxy-server=http://" + chosenProxy;
|
||||||
options.addArguments(finalProxy);
|
options.addArguments(finalProxy);
|
||||||
org.openqa.selenium.Proxy httpProxy = new org.openqa.selenium.Proxy();
|
org.openqa.selenium.Proxy httpProxy = new org.openqa.selenium.Proxy();
|
||||||
httpProxy.setHttpProxy(chosenProxy).setSslProxy(chosenProxy);
|
httpProxy.setHttpProxy(chosenProxy).setSslProxy(chosenProxy);
|
||||||
options.setCapability(CapabilityType.PROXY, httpProxy);
|
options.setCapability(CapabilityType.PROXY, httpProxy);
|
||||||
logger.info("HTTP(S) proxy настроен: {}{}", scheme, chosenProxy);
|
logger.info("HTTP(S) proxy настроен: http://{}", chosenProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class ProxyManager
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ProxyManager.class);
|
private static final Logger logger = LoggerFactory.getLogger(ProxyManager.class);
|
||||||
|
|
||||||
private final String API_URL = "https://papaproxy.net/api/getproxy/?format=json&type=http_ip&login=%s&password=%s";
|
private static final String API_URL = "https://px6.link/api/cecd79b327-8f5b6b51aa-63cc268d0a/getproxy?state=active&limit=1000";
|
||||||
private final List<String> proxyList = new ArrayList<>();
|
private final List<String> proxyList = new ArrayList<>();
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
@Value("${proxyLogin}")
|
@Value("${proxyLogin}")
|
||||||
@ -34,22 +34,24 @@ public class ProxyManager
|
|||||||
|
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
String fullUrl = String.format(API_URL, proxyLogin, proxypass);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String response = sendRequest(fullUrl);
|
String response = sendRequest(API_URL);
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
Map<String, Object> root = mapper.readValue(response, Map.class);
|
||||||
for (MappingIterator<Map> it = mapper.readValues(mapper.createParser(response), Map.class); it.hasNext(); )
|
if (!"yes".equals(root.get("status"))) {
|
||||||
{
|
throw new RuntimeException("Ошибка получения прокси: " + root.get("error"));
|
||||||
Map<String, String> jsonNode = it.next();
|
}
|
||||||
String host = jsonNode.get("host");
|
Map<String, Map<String, Object>> proxies = (Map<String, Map<String, Object>>) root.get("list");
|
||||||
String port = jsonNode.get("port");
|
proxyList.clear();
|
||||||
|
for (Map<String, Object> proxy : proxies.values()) {
|
||||||
|
String host = (String) proxy.get("host");
|
||||||
|
String port = (String) proxy.get("port");
|
||||||
|
if (host != null && port != null) {
|
||||||
proxyList.add(host + ":" + port);
|
proxyList.add(host + ":" + port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
} catch (Exception e) {
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,8 +62,7 @@ public class ProxyManager
|
|||||||
*/
|
*/
|
||||||
public boolean hasProxies()
|
public boolean hasProxies()
|
||||||
{
|
{
|
||||||
return true;
|
return !proxyList.isEmpty();
|
||||||
// return !proxyList.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,18 +70,10 @@ public class ProxyManager
|
|||||||
*/
|
*/
|
||||||
public String getNextProxy()
|
public String getNextProxy()
|
||||||
{
|
{
|
||||||
// if (proxyList.isEmpty())
|
if (proxyList.isEmpty()) {
|
||||||
// {
|
return null;
|
||||||
// return null;
|
}
|
||||||
// }
|
return proxyList.get(random.nextInt(proxyList.size()));
|
||||||
// return proxyList.get(random.nextInt(proxyList.size()));
|
|
||||||
|
|
||||||
String host = "pool.proxy.market";
|
|
||||||
String port = "10000";
|
|
||||||
// return proxyLogin + ":" + proxypass + "@" + host + ":" + port;
|
|
||||||
|
|
||||||
//HARDCODE TRUSTED PROXY THROUGHPUT LOCAL
|
|
||||||
return "localhost:8080";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,33 +247,123 @@ public class GoogleRegistrationHandler
|
|||||||
public void fillBirthdayAndGenderPage(UserData userData)
|
public void fillBirthdayAndGenderPage(UserData userData)
|
||||||
{
|
{
|
||||||
logger.info("Заполнение страницы даты рождения и пола");
|
logger.info("Заполнение страницы даты рождения и пола");
|
||||||
|
try {
|
||||||
|
// День
|
||||||
|
WebElement dayInput = findElementWithWait(By.cssSelector("input[name='day']"));
|
||||||
|
int day = userData.getBirthDay() > 0 ? userData.getBirthDay() : 1 + random.nextInt(28);
|
||||||
|
typeWithRandomDelay(dayInput, String.valueOf(day));
|
||||||
|
|
||||||
WebElement dayInput = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.DAY_INPUT));
|
// Год
|
||||||
WebElement monthSelect = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.MONTH_SELECT));
|
WebElement yearInput = findElementWithWait(By.cssSelector("input[name='year']"));
|
||||||
WebElement yearInput = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.YEAR_INPUT));
|
int year = userData.getBirthYear() > 1900 ? userData.getBirthYear() : 1980 + random.nextInt(30);
|
||||||
WebElement genderSelect = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.GENDER_SELECT));
|
typeWithRandomDelay(yearInput, String.valueOf(year));
|
||||||
|
|
||||||
// Заполняем день
|
// Месяц (кастомный дропдаун)
|
||||||
typeWithRandomDelay(dayInput, String.valueOf(userData.getBirthDay()));
|
try {
|
||||||
|
WebElement monthDropdown = null;
|
||||||
|
try {
|
||||||
|
monthDropdown = driver.findElement(By.xpath("//div[@role='combobox'][.//span[text()='Month']]"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
List<WebElement> comboboxes = driver.findElements(By.xpath("//div[@role='combobox']"));
|
||||||
|
if (!comboboxes.isEmpty()) {
|
||||||
|
monthDropdown = comboboxes.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (monthDropdown == null) {
|
||||||
|
logger.error("Не удалось найти дропдаун месяца!");
|
||||||
|
makeScreenshot("month_dropdown_not_found");
|
||||||
|
} else {
|
||||||
|
logger.info("Найден дропдаун месяца: {}", monthDropdown.getAttribute("outerHTML"));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].click();", monthDropdown);
|
||||||
|
Thread.sleep(500);
|
||||||
|
// Ищем ul с опциями только для месяца
|
||||||
|
WebElement monthList = null;
|
||||||
|
try {
|
||||||
|
monthList = monthDropdown.findElement(By.xpath("following-sibling::div/ul"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Не удалось найти ul с опциями месяца: {}", e.getMessage());
|
||||||
|
makeScreenshot("month_ul_not_found");
|
||||||
|
}
|
||||||
|
final int selectedMonth = userData.getBirthMonth() > 0 ? userData.getBirthMonth() : 1 + random.nextInt(12);
|
||||||
|
List<WebElement> monthOptions = monthList != null ? monthList.findElements(By.cssSelector("li[role='option'][data-value]")) : List.of();
|
||||||
|
WebElement monthOption = monthOptions.stream().filter(opt -> String.valueOf(selectedMonth).equals(opt.getAttribute("data-value"))).findFirst().orElse(null);
|
||||||
|
if (monthOption == null && !monthOptions.isEmpty()) {
|
||||||
|
monthOption = monthOptions.get(random.nextInt(monthOptions.size()));
|
||||||
|
logger.warn("Не найден нужный месяц, выбран случайный: {}", monthOption.getText());
|
||||||
|
}
|
||||||
|
if (monthOption != null) {
|
||||||
|
logger.info("Кликаю по опции месяца: {}", monthOption.getAttribute("outerHTML"));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].click();", monthOption);
|
||||||
|
} else {
|
||||||
|
logger.error("Не удалось найти ни одного варианта месяца!");
|
||||||
|
makeScreenshot("month_dropdown_not_found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Ошибка при выборе месяца: {}", e.getMessage());
|
||||||
|
makeScreenshot("month_dropdown_error");
|
||||||
|
}
|
||||||
|
|
||||||
// Выбираем месяц из выпадающего списка
|
// Пол (кастомный дропдаун)
|
||||||
Select monthDropdown = new Select(monthSelect);
|
try {
|
||||||
monthDropdown.selectByValue(String.valueOf(userData.getBirthMonth()));
|
WebElement genderDropdown = null;
|
||||||
|
try {
|
||||||
// Заполняем год
|
genderDropdown = driver.findElement(By.xpath("//div[@role='combobox'][.//span[text()='Gender']]"));
|
||||||
typeWithRandomDelay(yearInput, String.valueOf(userData.getBirthYear()));
|
} catch (Exception e) {
|
||||||
|
List<WebElement> comboboxes = driver.findElements(By.xpath("//div[@role='combobox']"));
|
||||||
// Выбираем пол
|
if (comboboxes.size() > 1) {
|
||||||
Select genderDropdown = new Select(genderSelect);
|
genderDropdown = comboboxes.get(1);
|
||||||
// 1 - Male, 2 - Female
|
}
|
||||||
genderDropdown.selectByValue(userData.getGender() == UserData.Gender.MALE ? "1" : "2");
|
}
|
||||||
|
if (genderDropdown == null) {
|
||||||
|
logger.error("Не удалось найти дропдаун пола!");
|
||||||
|
makeScreenshot("gender_dropdown_not_found");
|
||||||
|
} else {
|
||||||
|
logger.info("Найден дропдаун пола: {}", genderDropdown.getAttribute("outerHTML"));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].click();", genderDropdown);
|
||||||
|
Thread.sleep(500);
|
||||||
|
// Ищем ul с опциями только для пола
|
||||||
|
WebElement genderList = null;
|
||||||
|
try {
|
||||||
|
genderList = genderDropdown.findElement(By.xpath("following-sibling::div/ul"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Не удалось найти ul с опциями пола: {}", e.getMessage());
|
||||||
|
makeScreenshot("gender_ul_not_found");
|
||||||
|
}
|
||||||
|
final String genderValue;
|
||||||
|
if (userData.getGender() != null) {
|
||||||
|
genderValue = userData.getGender().toString().equals("MALE") ? "1" : (userData.getGender().toString().equals("FEMALE") ? "2" : null);
|
||||||
|
} else {
|
||||||
|
genderValue = null;
|
||||||
|
}
|
||||||
|
List<WebElement> genderOptions = genderList != null ? genderList.findElements(By.cssSelector("li[role='option'][data-value]")) : List.of();
|
||||||
|
WebElement genderOption = genderOptions.stream().filter(opt -> genderValue != null && genderValue.equals(opt.getAttribute("data-value"))).findFirst().orElse(null);
|
||||||
|
if (genderOption == null && !genderOptions.isEmpty()) {
|
||||||
|
genderOption = genderOptions.get(random.nextInt(genderOptions.size()));
|
||||||
|
logger.warn("Не найден нужный пол, выбран случайный: {}", genderOption.getText());
|
||||||
|
}
|
||||||
|
if (genderOption != null) {
|
||||||
|
logger.info("Кликаю по опции пола: {}", genderOption.getAttribute("outerHTML"));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].click();", genderOption);
|
||||||
|
} else {
|
||||||
|
logger.error("Не удалось найти ни одного варианта пола!");
|
||||||
|
makeScreenshot("gender_dropdown_not_found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Ошибка при выборе пола: {}", e.getMessage());
|
||||||
|
makeScreenshot("gender_dropdown_error");
|
||||||
|
}
|
||||||
|
|
||||||
// Нажимаем кнопку "Next"
|
// Нажимаем кнопку "Next"
|
||||||
WebElement nextButton = findElementWithWait(
|
WebElement nextButton = findElementWithWait(By.cssSelector(GoogleRegistrationSelectors.NEXT_BUTTON_BIRTHDAY_PAGE));
|
||||||
By.cssSelector(GoogleRegistrationSelectors.NEXT_BUTTON_BIRTHDAY_PAGE));
|
|
||||||
nextButton.click();
|
nextButton.click();
|
||||||
|
|
||||||
logger.info("Страница даты рождения и пола заполнена успешно");
|
logger.info("Страница даты рождения и пола заполнена успешно");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Ошибка при заполнении даты рождения и пола: {}", e.getMessage());
|
||||||
|
makeScreenshot("birthday_gender_error");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1036,241 +1126,171 @@ public class GoogleRegistrationHandler
|
|||||||
WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(5)); // Короткое ожидание для Next
|
WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(5)); // Короткое ожидание для Next
|
||||||
|
|
||||||
// --- Экран "Choose your settings" ---
|
// --- Экран "Choose your settings" ---
|
||||||
// logger.info("Обработка экрана 'Choose your settings'...");
|
logger.info("Обработка экрана 'Choose your settings'...");
|
||||||
// sleep(2000);
|
sleep(2000);
|
||||||
// takeScreenshot(driver, "choose_settings_screen");
|
takeScreenshot(driver, "choose_settings_screen");
|
||||||
//
|
|
||||||
// // Пробуем нажать опцию "Choose in 1 step" если она доступна
|
|
||||||
// boolean oneStepClicked = false;
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// // Сначала пробуем более надежный XPath
|
|
||||||
// String oneStepXPath = "//div[@role='radiogroup']//div[.//span[contains(text(), 'Choose in 1 step')]]//input";
|
|
||||||
// WebElement oneStepRadio = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(oneStepXPath)));
|
|
||||||
// // Кликаем на родительский div
|
|
||||||
// WebElement parentDiv = oneStepRadio.findElement(By.xpath("./ancestor::div[@role='radio']"));
|
|
||||||
// wait.until(ExpectedConditions.elementToBeClickable(parentDiv)).click();
|
|
||||||
// logger.info("Нажата опция 'Choose in 1 step' через XPath");
|
|
||||||
// oneStepClicked = true;
|
|
||||||
// }
|
|
||||||
// catch (Exception xpathEx)
|
|
||||||
// {
|
|
||||||
// logger.warn("Не удалось нажать на 'Choose in 1 step' через XPath: {}", xpathEx.getMessage());
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// // Пробуем менее надежный data-value селектор
|
|
||||||
// WebElement oneStepOption = wait.until(ExpectedConditions.elementToBeClickable(
|
|
||||||
// By.cssSelector("div[jsname='ornU0b'][data-value='1']")));
|
|
||||||
// oneStepOption.click();
|
|
||||||
// logger.info("Нажата опция 'Choose in 1 step' стандартным методом (data-value)");
|
|
||||||
// oneStepClicked = true;
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.warn("Не удалось нажать на 'Choose in 1 step' стандартным методом: {}", e.getMessage());
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// // Пробуем JS как крайний вариант
|
|
||||||
// ((JavascriptExecutor) driver).executeScript(
|
|
||||||
// "document.querySelector(\"div[jsname='ornU0b'][data-value='1']\").click();");
|
|
||||||
// logger.info("Нажата опция 'Choose in 1 step' через JavaScript");
|
|
||||||
// oneStepClicked = true;
|
|
||||||
// }
|
|
||||||
// catch (Exception jsEx)
|
|
||||||
// {
|
|
||||||
// logger.error("Не удалось нажать на 'Choose in 1 step' никаким способом: {}", jsEx.getMessage());
|
|
||||||
// // Если не удалось выбрать, возможно, стоит прервать или перейти к следующему шагу, если он уже выбран
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Если успешно кликнули "Choose in 1 step", *немедленно* нажимаем "Next" для этого экрана
|
|
||||||
// if (oneStepClicked)
|
|
||||||
// {
|
|
||||||
// sleep(1000); // Пауза после клика на радио
|
|
||||||
// takeScreenshot(driver, "after_choose_in_one_step");
|
|
||||||
// logger.info("Ищем и нажимаем кнопку 'Next' *сразу после* выбора 'Choose in 1 step'...");
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// String nextButtonXPath = "//button[@jsname='LgbsSe' and .//span[text()='Next']]";
|
|
||||||
// WebElement nextButton = shortWait.until(
|
|
||||||
// ExpectedConditions.elementToBeClickable(By.xpath(nextButtonXPath)));
|
|
||||||
// nextButton.click();
|
|
||||||
// logger.info("Кнопка 'Next' нажата после 'Choose in 1 step'.");
|
|
||||||
// sleep(2500); // Увеличиваем паузу для загрузки следующей страницы
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.error("Не удалось найти или нажать кнопку 'Next' сразу после 'Choose in 1 step': {}",
|
|
||||||
// e.getMessage());
|
|
||||||
// makeScreenshot("choose_settings_next_button_error");
|
|
||||||
// // Продолжаем выполнение, т.к. возможно, мы уже на следующем шаге или кнопка Next другая
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// logger.warn("Не удалось кликнуть 'Choose in 1 step', пропускаем нажатие Next на этом шаге.");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // --- Последующие экраны (Confirm/Reject/I agree) ---
|
|
||||||
// // Эта логика остается для обработки экранов, которые могут появиться ПОСЛЕ нажатия Next выше
|
|
||||||
//
|
|
||||||
// takeScreenshot(driver, "privacy_settings_intermediate");
|
|
||||||
//
|
|
||||||
// // Пробуем нажать "Reject all" если она доступна (может появиться на следующем шаге)
|
|
||||||
// logger.info("Проверка наличия кнопки 'Reject all'...");
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// WebElement rejectAllButton = shortWait.until(
|
|
||||||
// ExpectedConditions.elementToBeClickable( // Используем shortWait
|
|
||||||
// By.xpath("//button[contains(@aria-label, 'Reject all') or contains(., 'Reject all')]")));
|
|
||||||
// rejectAllButton.click();
|
|
||||||
// logger.info("Нажата кнопка 'Reject all'");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_reject_all");
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.info("Кнопка 'Reject all' не найдена или не кликабельна: {}", e.getMessage());
|
|
||||||
// // Пробуем JS как запасной вариант
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// ((JavascriptExecutor) driver).executeScript(
|
|
||||||
// "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Reject all')).click();");
|
|
||||||
// logger.info("Нажата кнопка 'Reject all' через JavaScript");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_reject_all_js");
|
|
||||||
// }
|
|
||||||
// catch (Exception jsEx)
|
|
||||||
// {
|
|
||||||
// logger.info("Кнопка 'Reject all' не найдена и через JavaScript: {}", jsEx.getMessage());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Пробуем нажать "Confirm" если она доступна
|
|
||||||
// logger.info("Проверка наличия кнопки 'Confirm'...");
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// WebElement confirmButton = shortWait.until(ExpectedConditions.elementToBeClickable( // Используем shortWait
|
|
||||||
// By.xpath("//button[contains(@aria-label, 'Confirm') or contains(., 'Confirm')]")));
|
|
||||||
// confirmButton.click();
|
|
||||||
// logger.info("Нажата кнопка 'Confirm'");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_confirm");
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.info("Кнопка 'Confirm' не найдена или не кликабельна: {}", e.getMessage());
|
|
||||||
// // Пробуем JS
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// ((JavascriptExecutor) driver).executeScript(
|
|
||||||
// "Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Confirm')).click();");
|
|
||||||
// logger.info("Нажата кнопка 'Confirm' через JavaScript");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_confirm_js");
|
|
||||||
// }
|
|
||||||
// catch (Exception jsEx)
|
|
||||||
// {
|
|
||||||
// logger.info("Кнопка 'Confirm' не найдена и через JavaScript: {}", jsEx.getMessage());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Нажимаем "I agree" на странице условий использования
|
boolean oneStepClicked = false;
|
||||||
logger.info("Проверка наличия кнопки 'I agree'...");
|
try {
|
||||||
|
// Находим radio-кнопку по data-value
|
||||||
|
WebElement oneStepRadio = wait.until(ExpectedConditions.elementToBeClickable(
|
||||||
|
By.cssSelector("div[role='radio'][data-value='1']")
|
||||||
|
));
|
||||||
|
// Скроллим к элементу
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", oneStepRadio);
|
||||||
|
sleep(300);
|
||||||
|
oneStepRadio.click();
|
||||||
|
logger.info("Нажата опция 'Choose in 1 step' по CSS-селектору");
|
||||||
|
// Ждем, что aria-checked станет true
|
||||||
|
wait.until(ExpectedConditions.attributeToBe(oneStepRadio, "aria-checked", "true"));
|
||||||
|
oneStepClicked = true;
|
||||||
|
} catch (Exception cssEx) {
|
||||||
|
logger.warn("Не удалось нажать на 'Choose in 1 step' по CSS: {}", cssEx.getMessage());
|
||||||
|
try {
|
||||||
|
// Fallback: клик через JS
|
||||||
|
((JavascriptExecutor) driver).executeScript(
|
||||||
|
"var el = document.querySelector('div[role=\\'radio\\'][data-value=\\'1\\']'); if(el) el.click();"
|
||||||
|
);
|
||||||
|
logger.info("Нажата опция 'Choose in 1 step' через JavaScript");
|
||||||
|
oneStepClicked = true;
|
||||||
|
} catch (Exception jsEx) {
|
||||||
|
logger.error("Не удалось нажать на 'Choose in 1 step' никаким способом: {}", jsEx.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если успешно кликнули "Choose in 1 step", *немедленно* нажимаем "Next" для этого экрана
|
||||||
|
if (oneStepClicked) {
|
||||||
|
sleep(1000); // Пауза после клика на радио
|
||||||
|
takeScreenshot(driver, "after_choose_in_one_step");
|
||||||
|
logger.info("Ищем и нажимаем кнопку 'Next' *сразу после* выбора 'Choose in 1 step'...");
|
||||||
|
try {
|
||||||
|
WebElement nextButton = shortWait.until(
|
||||||
|
ExpectedConditions.elementToBeClickable(
|
||||||
|
By.xpath("//button[@jsname='LgbsSe' and .//span[text()='Next']]")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
nextButton.click();
|
||||||
|
logger.info("Кнопка 'Next' нажата после 'Choose in 1 step'.");
|
||||||
|
sleep(2500); // Пауза для загрузки следующей страницы
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Не удалось найти или нажать кнопку 'Next' сразу после 'Choose in 1 step': {}", e.getMessage());
|
||||||
|
makeScreenshot("choose_settings_next_button_error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("Не удалось кликнуть 'Choose in 1 step', пропускаем нажатие Next на этом шаге.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Последующие экраны (Confirm/Reject/I agree) ---
|
||||||
|
takeScreenshot(driver, "privacy_settings_intermediate");
|
||||||
|
|
||||||
|
// Пробуем нажать "Reject all" если она доступна (может появиться на следующем шаге)
|
||||||
|
logger.info("Проверка наличия кнопки 'Reject all'...");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WebElement agreeButton = wait.until(ExpectedConditions.elementToBeClickable(
|
WebElement rejectAllButton = shortWait.until(
|
||||||
By.xpath(GoogleRegistrationSelectors.I_AGREE_BUTTON_XPATH)));
|
ExpectedConditions.elementToBeClickable( // Используем shortWait
|
||||||
agreeButton.click();
|
By.xpath("//button[contains(@aria-label, 'Reject all') or contains(., 'Reject all')]")));
|
||||||
logger.info("Успешно нажата кнопка 'I agree' по XPath селектору");
|
rejectAllButton.click();
|
||||||
|
logger.info("Нажата кнопка 'Reject all'");
|
||||||
sleep(2000);
|
sleep(2000);
|
||||||
takeScreenshot(driver, "after_i_agree");
|
takeScreenshot(driver, "after_reject_all");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.warn("Не удалось нажать на 'I agree' по XPath селектору: {}", e.getMessage());
|
logger.info("Кнопка 'Reject all' не найдена или не кликабельна: {}", e.getMessage());
|
||||||
// Пробуем другие селекторы и JS...
|
// Пробуем JS как запасной вариант
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WebElement agreeButton = wait.until(ExpectedConditions.elementToBeClickable(
|
|
||||||
By.cssSelector(GoogleRegistrationSelectors.I_AGREE_BUTTON)));
|
|
||||||
agreeButton.click();
|
|
||||||
logger.info("Успешно нажата кнопка 'I agree' по CSS селектору");
|
|
||||||
sleep(2000);
|
|
||||||
takeScreenshot(driver, "after_i_agree_css");
|
|
||||||
}
|
|
||||||
catch (Exception cssEx)
|
|
||||||
{
|
|
||||||
logger.warn("Не удалось нажать на 'I agree' по CSS селектору: {}", cssEx.getMessage());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// JavaScript-клик для кнопки "I agree"
|
|
||||||
((JavascriptExecutor) driver).executeScript(
|
((JavascriptExecutor) driver).executeScript(
|
||||||
"Array.from(document.querySelectorAll('button')).find(el => " + "el.textContent.includes('I agree') || " + "(el.querySelector('span') && el.querySelector('span').textContent.includes('I agree'))).click();");
|
"Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Reject all')).click();");
|
||||||
logger.info("Нажата кнопка 'I agree' через JavaScript");
|
logger.info("Нажата кнопка 'Reject all' через JavaScript");
|
||||||
sleep(2000);
|
sleep(2000);
|
||||||
takeScreenshot(driver, "after_i_agree_js");
|
takeScreenshot(driver, "after_reject_all_js");
|
||||||
}
|
}
|
||||||
catch (Exception jsEx)
|
catch (Exception jsEx)
|
||||||
{
|
{
|
||||||
|
logger.info("Кнопка 'Reject all' не найдена и через JavaScript: {}", jsEx.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Пробуем нажать "Confirm" если она доступна
|
||||||
|
logger.info("Проверка наличия кнопки 'Confirm'...");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebElement confirmButton = shortWait.until(ExpectedConditions.elementToBeClickable( // Используем shortWait
|
||||||
|
By.xpath("//button[contains(@aria-label, 'Confirm') or contains(., 'Confirm')]")));
|
||||||
|
confirmButton.click();
|
||||||
|
logger.info("Нажата кнопка 'Confirm'");
|
||||||
|
sleep(2000);
|
||||||
|
takeScreenshot(driver, "after_confirm");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.info("Кнопка 'Confirm' не найдена или не кликабельна: {}", e.getMessage());
|
||||||
|
// Пробуем JS
|
||||||
|
try
|
||||||
|
{
|
||||||
|
((JavascriptExecutor) driver).executeScript(
|
||||||
|
"Array.from(document.querySelectorAll('button')).find(el => el.textContent.includes('Confirm')).click();");
|
||||||
|
logger.info("Нажата кнопка 'Confirm' через JavaScript");
|
||||||
|
sleep(2000);
|
||||||
|
takeScreenshot(driver, "after_confirm_js");
|
||||||
|
}
|
||||||
|
catch (Exception jsEx)
|
||||||
|
{
|
||||||
|
logger.info("Кнопка 'Confirm' не найдена и через JavaScript: {}", jsEx.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Кнопка "I agree" на Privacy and Terms ---
|
||||||
|
logger.info("Проверка наличия кнопки 'I agree'...");
|
||||||
|
try {
|
||||||
|
// Сначала пробуем по XPath (ищет span с текстом I agree)
|
||||||
|
WebElement agreeButton = shortWait.until(ExpectedConditions.elementToBeClickable(
|
||||||
|
By.xpath("//button[@jsname='LgbsSe' and .//span[text()='I agree']]")
|
||||||
|
));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", agreeButton);
|
||||||
|
sleep(300);
|
||||||
|
agreeButton.click();
|
||||||
|
logger.info("Кнопка 'I agree' нажата по XPath");
|
||||||
|
sleep(2000);
|
||||||
|
takeScreenshot(driver, "after_i_agree");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("Не удалось нажать на 'I agree' по XPath: {}", e.getMessage());
|
||||||
|
// Пробуем по CSS
|
||||||
|
try {
|
||||||
|
WebElement agreeButton = shortWait.until(ExpectedConditions.elementToBeClickable(
|
||||||
|
By.cssSelector("button[jsname='LgbsSe'] span.VfPpkd-vQzf8d")
|
||||||
|
));
|
||||||
|
// Проверяем текст
|
||||||
|
if ("I agree".equals(agreeButton.getText().trim())) {
|
||||||
|
WebElement button = agreeButton.findElement(By.xpath("./ancestor::button"));
|
||||||
|
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", button);
|
||||||
|
sleep(300);
|
||||||
|
button.click();
|
||||||
|
logger.info("Кнопка 'I agree' нажата по CSS");
|
||||||
|
sleep(2000);
|
||||||
|
takeScreenshot(driver, "after_i_agree_css");
|
||||||
|
} else {
|
||||||
|
throw new Exception("Не найден нужный span с текстом I agree");
|
||||||
|
}
|
||||||
|
} catch (Exception cssEx) {
|
||||||
|
logger.warn("Не удалось нажать на 'I agree' по CSS: {}", cssEx.getMessage());
|
||||||
|
// Пробуем через JS
|
||||||
|
try {
|
||||||
|
((JavascriptExecutor) driver).executeScript(
|
||||||
|
"Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'I agree' || (b.querySelector('span') && b.querySelector('span').textContent.trim() === 'I agree'))?.click();"
|
||||||
|
);
|
||||||
|
logger.info("Кнопка 'I agree' нажата через JavaScript");
|
||||||
|
sleep(2000);
|
||||||
|
takeScreenshot(driver, "after_i_agree_js");
|
||||||
|
} catch (Exception jsEx) {
|
||||||
logger.error("Не удалось нажать на 'I agree' никаким способом: {}", jsEx.getMessage());
|
logger.error("Не удалось нажать на 'I agree' никаким способом: {}", jsEx.getMessage());
|
||||||
// Если даже JS не сработал, возможно, стоит прервать регистрацию
|
|
||||||
throw new RuntimeException("Не удалось нажать кнопку 'I agree'");
|
throw new RuntimeException("Не удалось нажать кнопку 'I agree'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// --- Конец блока 'I agree' ---
|
||||||
// Проверяем, появился ли диалог "Confirm personalisation?"
|
|
||||||
// logger.info("Проверка наличия диалога 'Confirm personalisation?'...");
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// sleep(1000);
|
|
||||||
// takeScreenshot(driver, "check_personalisation_dialog");
|
|
||||||
//
|
|
||||||
// // Ищем кнопку "Confirm" в диалоге
|
|
||||||
// WebElement confirmPersonalisationButton = shortWait.until(ExpectedConditions.elementToBeClickable(
|
|
||||||
// By.xpath(GoogleRegistrationSelectors.CONFIRM_PERSONALISATION_XPATH)));
|
|
||||||
// confirmPersonalisationButton.click();
|
|
||||||
// logger.info("Успешно нажата кнопка 'Confirm' в диалоге персонализации по XPath селектору");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_confirm_personalisation");
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.info("Диалог 'Confirm personalisation?' не обнаружен или не кликабелен: {}", e.getMessage());
|
|
||||||
// // Пробуем JS
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// ((JavascriptExecutor) driver).executeScript(
|
|
||||||
// "var buttons = Array.from(document.querySelectorAll('button')); " + "for (var i = 0; i < buttons.length; i++) { " + " var btn = buttons[i]; " + " if ((btn.textContent && btn.textContent.indexOf('Confirm') >= 0) || " + " (btn.getAttribute('jsname') === 'ssJRIf')) { " + " btn.click(); break; " + " } " + "}");
|
|
||||||
// logger.info("Нажата кнопка 'Confirm' в диалоге персонализации через JavaScript");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_confirm_personalisation_js");
|
|
||||||
// }
|
|
||||||
// catch (Exception jsEx)
|
|
||||||
// {
|
|
||||||
// logger.info("Кнопка 'Confirm' в диалоге персонализации не найдена и через JavaScript: {}",
|
|
||||||
// jsEx.getMessage());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Проверяем наличие финальной кнопки Next (если она есть после всех шагов)
|
|
||||||
// logger.info("Проверка наличия финальной кнопки 'Next'...");
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// WebElement finalNextButton = shortWait.until(ExpectedConditions.elementToBeClickable(
|
|
||||||
// By.xpath("//button[@jsname='LgbsSe' and .//span[text()='Next']]")));
|
|
||||||
// finalNextButton.click();
|
|
||||||
// logger.info("Нажата финальная кнопка 'Next'.");
|
|
||||||
// sleep(2000);
|
|
||||||
// takeScreenshot(driver, "after_final_next_button");
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// logger.info("Финальная кнопка 'Next' не найдена или не кликабельна (возможно, ее нет): {}", e.getMessage());
|
|
||||||
// }
|
|
||||||
|
|
||||||
takeScreenshot(driver, "after_privacy_settings_attempts");
|
takeScreenshot(driver, "after_privacy_settings_attempts");
|
||||||
logger.info("Завершена обработка настроек конфиденциальности");
|
logger.info("Завершена обработка настроек конфиденциальности");
|
||||||
|
@ -19,9 +19,9 @@ public class SmsActivateService
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
private final String API_URL = "https://give-sms.com/stubs/handler_api.php";
|
private final String API_URL = "https://sms-activate.ru/stubs/handler_api.php";
|
||||||
|
|
||||||
private final String API2_URL = "https://api.sms-activate.world/v2/api/";
|
private final String API2_URL = "https://sms-activate.ru/stubs/handler_api.php";
|
||||||
|
|
||||||
@Value("${default_country}")
|
@Value("${default_country}")
|
||||||
private int defaultCountry;
|
private int defaultCountry;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#sms_activate_api_key: cd64e325c15813edc722867BB6171B94
|
#sms_activate_api_key: cd64e325c15813edc722867BB6171B94
|
||||||
sms_activate_api_key: pPmJIKmh7RepulVySCPf
|
sms_activate_api_key: 96615419f3eccA65f7679ce65cA17dA9
|
||||||
|
|
||||||
captcha_api_key: deeb0d134a47e88dffab6dc48a5a0906
|
captcha_api_key: deeb0d134a47e88dffab6dc48a5a0906
|
||||||
captcha_service_type: TWOCAPTCHA
|
captcha_service_type: TWOCAPTCHA
|
||||||
|
Reference in New Issue
Block a user