| Line 6... |
Line 6... |
| 6 |
import org.apache.logging.log4j.Logger;
|
6 |
import org.apache.logging.log4j.Logger;
|
| 7 |
import org.opencv.core.Mat;
|
7 |
import org.opencv.core.Mat;
|
| 8 |
import org.opencv.core.Size;
|
8 |
import org.opencv.core.Size;
|
| 9 |
import org.opencv.imgcodecs.Imgcodecs;
|
9 |
import org.opencv.imgcodecs.Imgcodecs;
|
| 10 |
import org.opencv.imgproc.Imgproc;
|
10 |
import org.opencv.imgproc.Imgproc;
|
| - |
|
11 |
import org.json.JSONObject;
|
| 11 |
import org.openqa.selenium.*;
|
12 |
import org.openqa.selenium.*;
|
| 12 |
import org.openqa.selenium.chrome.ChromeDriver;
|
13 |
import org.openqa.selenium.chrome.ChromeDriver;
|
| 13 |
import org.openqa.selenium.chrome.ChromeOptions;
|
14 |
import org.openqa.selenium.chrome.ChromeOptions;
|
| 14 |
import org.openqa.selenium.interactions.Actions;
|
15 |
import org.openqa.selenium.interactions.Actions;
|
| 15 |
import org.openqa.selenium.support.ui.ExpectedConditions;
|
16 |
import org.openqa.selenium.support.ui.ExpectedConditions;
|
| Line 19... |
Line 20... |
| 19 |
import javax.imageio.ImageIO;
|
20 |
import javax.imageio.ImageIO;
|
| 20 |
import java.awt.image.BufferedImage;
|
21 |
import java.awt.image.BufferedImage;
|
| 21 |
import java.io.File;
|
22 |
import java.io.File;
|
| 22 |
import java.time.LocalDate;
|
23 |
import java.time.LocalDate;
|
| 23 |
import java.time.format.DateTimeFormatter;
|
24 |
import java.time.format.DateTimeFormatter;
|
| - |
|
25 |
import java.time.Instant;
|
| - |
|
26 |
import java.time.ZoneId;
|
| 24 |
import java.util.HashMap;
|
27 |
import java.util.HashMap;
|
| 25 |
import java.util.List;
|
28 |
import java.util.List;
|
| 26 |
import java.util.Map;
|
29 |
import java.util.Map;
|
| 27 |
import java.util.concurrent.TimeUnit;
|
30 |
import java.util.concurrent.TimeUnit;
|
| 28 |
import java.util.stream.Collectors;
|
31 |
import java.util.stream.Collectors;
|
| Line 84... |
Line 87... |
| 84 |
WebDriverWait wait5Sec = new WebDriverWait(driver, 4);
|
87 |
WebDriverWait wait5Sec = new WebDriverWait(driver, 4);
|
| 85 |
WebElement slideButton;
|
88 |
WebElement slideButton;
|
| 86 |
Actions actionProvider = new Actions(driver);
|
89 |
Actions actionProvider = new Actions(driver);
|
| 87 |
do {
|
90 |
do {
|
| 88 |
driver.get("https://support.oppo.com/in/warranty-check/");
|
91 |
driver.get("https://support.oppo.com/in/warranty-check/");
|
| - |
|
92 |
installResponseCapture(driver);
|
| 89 |
try {
|
93 |
try {
|
| 90 |
driver.findElement(By.cssSelector(".cp-cookie-tip a.close")).click();
|
94 |
driver.findElement(By.cssSelector(".cp-cookie-tip a.close")).click();
|
| 91 |
} catch (Exception e) {
|
95 |
} catch (Exception e) {
|
| 92 |
}
|
96 |
}
|
| 93 |
|
97 |
|
| Line 148... |
Line 152... |
| 148 |
try {
|
152 |
try {
|
| 149 |
wait5Sec.until(ExpectedConditions.visibilityOfElementLocated(By.className("dx_captcha_basic_bar-inform")));
|
153 |
wait5Sec.until(ExpectedConditions.visibilityOfElementLocated(By.className("dx_captcha_basic_bar-inform")));
|
| 150 |
LOGGER.warn("Failed = " + counter);
|
154 |
LOGGER.warn("Failed = " + counter);
|
| 151 |
} catch (Exception notFailedException) {
|
155 |
} catch (Exception notFailedException) {
|
| 152 |
LOGGER.info("Success at attempt " + counter);
|
156 |
LOGGER.info("Success at attempt " + counter);
|
| - |
|
157 |
|
| 153 |
//List<WebElement> warrantyDateElements = driver.findElements(By.className("warranty-service--result_info__dateValue"));
|
158 |
// Read the JSON the page itself received rather than the
|
| 154 |
WebElement activationTimeElement = driver.findElement(By.xpath("//*[contains(text(), 'UTC+5.5') or contains(text(), 'Non-Activate')]"));
|
- |
|
| 155 |
//TODO: IF not found activationElement
|
159 |
// rendered text. The DOM value is built from two text nodes -- the
|
| 156 |
if (activationTimeElement != null) {
|
160 |
// date plus a "(UTC+x)" suffix derived from the browser timezone --
|
| 157 |
String activationDateString = activationTimeElement.getText().trim();
|
161 |
// and the old locator tested only the first, so it matched nothing.
|
| 158 |
LOGGER.info("Date -- " + activationDateString);
|
162 |
// The API carries regDate as epoch millis, which has no format or
|
| 159 |
try {
|
163 |
// timezone ambiguity at all.
|
| 160 |
dateMap.put(imei, LocalDate.parse(activationDateString.split(" ")[0], DateTimeFormatter.ofPattern("dd/MM/yyyy")));
|
- |
|
| 161 |
LOGGER.info("Date -- " + activationDateString);
|
164 |
String json = capturedResponse(driver);
|
| 162 |
} catch (Exception e) {
|
165 |
LocalDate activationDate = regDateFrom(json);
|
| - |
|
166 |
|
| 163 |
dateMap.put(imei, null);
|
167 |
if (json == null) {
|
| 164 |
}
|
168 |
LOGGER.warn("Result shown but no getDeviceInfo response captured for imei {}", imei);
|
| 165 |
} else {
|
169 |
} else {
|
| 166 |
LOGGER.warn("Could not capture date");
|
170 |
LOGGER.info("Activation lookup for {} -> {}", imei,
|
| 167 |
dateMap.put(imei, null);
|
171 |
activationDate != null ? activationDate : "no activation date");
|
| 168 |
}
|
172 |
}
|
| - |
|
173 |
// Always record the imei, even with a null date: findElement used to
|
| - |
|
174 |
// throw here, so the row was never written and came back every run.
|
| - |
|
175 |
dateMap.put(imei, activationDate);
|
| - |
|
176 |
clearCapture(driver);
|
| - |
|
177 |
|
| 169 |
if (dateMap.size() == imeis.size()) {
|
178 |
if (dateMap.size() == imeis.size()) {
|
| 170 |
return dateMap;
|
179 |
return dateMap;
|
| 171 |
}
|
180 |
}
|
| 172 |
WebElement checkAgainButton = driver.findElement(By.className("c-btn"));
|
181 |
WebElement checkAgainButton = driver.findElement(By.className("c-btn"));
|
| 173 |
captchaNotBroken = false;
|
182 |
captchaNotBroken = false;
|
| Line 209... |
Line 218... |
| 209 |
|
218 |
|
| 210 |
return dateMap;
|
219 |
return dateMap;
|
| 211 |
}
|
220 |
}
|
| 212 |
|
221 |
|
| 213 |
|
222 |
|
| - |
|
223 |
/** Stash the getDeviceInfo response on window as the page receives it. */
|
| - |
|
224 |
private void installResponseCapture(WebDriver driver) {
|
| - |
|
225 |
try {
|
| - |
|
226 |
((JavascriptExecutor) driver).executeScript(
|
| - |
|
227 |
"if (!window.__oppoCapInstalled) {"
|
| - |
|
228 |
+ " window.__oppoCapInstalled = true; window.__oppoResp = null;"
|
| - |
|
229 |
+ " var O = XMLHttpRequest.prototype.open;"
|
| - |
|
230 |
+ " XMLHttpRequest.prototype.open = function(m,u){"
|
| - |
|
231 |
+ " this.addEventListener('load', function(){"
|
| - |
|
232 |
+ " try { if (String(u).indexOf('getDeviceInfo') !== -1) window.__oppoResp = this.responseText; } catch(e){}"
|
| - |
|
233 |
+ " });"
|
| - |
|
234 |
+ " return O.apply(this, arguments);"
|
| - |
|
235 |
+ " };"
|
| - |
|
236 |
+ "}");
|
| - |
|
237 |
} catch (Exception e) {
|
| - |
|
238 |
LOGGER.warn("Could not install the response capture hook: " + e.getMessage());
|
| - |
|
239 |
}
|
| - |
|
240 |
}
|
| - |
|
241 |
|
| - |
|
242 |
private String capturedResponse(WebDriver driver) {
|
| - |
|
243 |
try {
|
| - |
|
244 |
Object v = ((JavascriptExecutor) driver).executeScript("return window.__oppoResp || null;");
|
| - |
|
245 |
return v == null ? null : v.toString();
|
| - |
|
246 |
} catch (Exception e) {
|
| - |
|
247 |
return null;
|
| - |
|
248 |
}
|
| - |
|
249 |
}
|
| - |
|
250 |
|
| - |
|
251 |
private void clearCapture(WebDriver driver) {
|
| - |
|
252 |
try {
|
| - |
|
253 |
((JavascriptExecutor) driver).executeScript("window.__oppoResp = null;");
|
| - |
|
254 |
} catch (Exception ignored) {
|
| - |
|
255 |
}
|
| - |
|
256 |
}
|
| - |
|
257 |
|
| - |
|
258 |
/** data.regDate is epoch millis; absent or blank means the device is not activated yet. */
|
| - |
|
259 |
private LocalDate regDateFrom(String json) {
|
| - |
|
260 |
if (json == null) return null;
|
| - |
|
261 |
try {
|
| - |
|
262 |
JSONObject data = new JSONObject(json).optJSONObject("data");
|
| - |
|
263 |
if (data == null) return null;
|
| - |
|
264 |
String reg = data.optString("regDate", "");
|
| - |
|
265 |
if (reg == null || reg.trim().isEmpty() || "null".equals(reg)) return null;
|
| - |
|
266 |
return Instant.ofEpochMilli(Long.parseLong(reg.trim()))
|
| - |
|
267 |
.atZone(ZoneId.of("Asia/Kolkata")).toLocalDate();
|
| - |
|
268 |
} catch (Exception e) {
|
| - |
|
269 |
LOGGER.warn("Could not read regDate from the Oppo response: " + e.getMessage());
|
| - |
|
270 |
return null;
|
| - |
|
271 |
}
|
| - |
|
272 |
}
|
| - |
|
273 |
|
| 214 |
private int checkDistance(WebDriver driver, WebDriverWait wait3Sec, Actions actionProvider, double distance, WebElement slideButton) throws Exception {
|
274 |
private int checkDistance(WebDriver driver, WebDriverWait wait3Sec, Actions actionProvider, double distance, WebElement slideButton) throws Exception {
|
| 215 |
|
275 |
|
| 216 |
//actionProvider.moveToElement(slideButton).clickAndHold().moveByOffset(1, 0).perform();
|
276 |
//actionProvider.moveToElement(slideButton).clickAndHold().moveByOffset(1, 0).perform();
|
| 217 |
actionProvider.moveByOffset(15, 0).perform();
|
277 |
actionProvider.moveByOffset(15, 0).perform();
|
| 218 |
String fileName2 = "/tmp/" + Thread.currentThread().getName() + "-moved.png";
|
278 |
String fileName2 = "/tmp/" + Thread.currentThread().getName() + "-moved.png";
|