All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.seleniumtests.uipage.uielements.UiElement Maven / Gradle / Ivy

There is a newer version: 5.1.13
Show newest version
/**
 * Orignal work: Copyright 2015 www.seleniumtests.com
 * Modified work: Copyright 2016 www.infotel.com
 * 				Copyright 2017-2019 B.Hecquet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.seleniumtests.uipage.uielements;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.logging.log4j.Logger;
import org.openqa.selenium.Point;
import org.openqa.selenium.remote.ScreenshotException;

import com.seleniumtests.connectors.selenium.SeleniumRobotSnapshotServerConnector;
import com.seleniumtests.connectors.selenium.fielddetector.Field;
import com.seleniumtests.connectors.selenium.fielddetector.Label;
import com.seleniumtests.core.SeleniumTestsContextManager;
import com.seleniumtests.customexception.ConfigurationException;
import com.seleniumtests.customexception.ImageSearchException;
import com.seleniumtests.customexception.ScenarioException;
import com.seleniumtests.driver.CustomEventFiringWebDriver;
import com.seleniumtests.driver.WebUIDriver;
import com.seleniumtests.driver.screenshots.ScreenShot;
import com.seleniumtests.driver.screenshots.ScreenshotUtil;
import com.seleniumtests.driver.screenshots.SnapshotTarget;
import com.seleniumtests.uipage.PageObject;
import com.seleniumtests.uipage.ReplayOnError;
import com.seleniumtests.util.helper.WaitHelper;
import com.seleniumtests.util.imaging.ImageDetector;
import com.seleniumtests.util.imaging.ImageProcessor;
import com.seleniumtests.util.logging.SeleniumRobotLogger;

import kong.unirest.json.JSONObject;

/**
 * Element which is found inside driver snapshot
 * @author behe
 *
 */
public class UiElement {
	
	/* 
	 * TODO
	 * - faire un reset entre 2 tests
	 */
	
	protected static final Logger logger = SeleniumRobotLogger.getLogger(UiElement.class);
	private static Map> fieldsPerPage;
	private static Map> labelsPerPage;
	
	// coordinates of the top-left corner of the viewport in the screen
	private static Map offsetPerPage;
	
	static {
		resetPageInformation();
	}
	
	private long actionDuration;
	private ElementType elementType;
	private ScreenshotUtil screenshotUtil;
	private ByUI by;
	private boolean resetSearch;
    private String origin  = null;
	protected Clock clock = Clock.systemUTC();

	protected Rectangle detectedObjectRectangle;

	public UiElement() {
		// for mocks
	}
	
	public UiElement(ByUI by) {
		this(by, false);
	}
	
	/**
	 * 
	 * @param by			search criteria
	 * @param resetSearch	if true, a new capture will be taken to refresh screen (in case GUI changed on this page)
	 */
	public UiElement(ByUI by, boolean resetSearch) {
		this.by = by;
		this.elementType = by.getType();
		
		origin = PageObject.getCallingPage(Thread.currentThread().getStackTrace());
		this.resetSearch = resetSearch;
	}

	/**
	 * Reset any information for any page. Mainly used for tests
	 */
	public static void resetPageInformation() {
		fieldsPerPage = Collections.synchronizedMap(new HashMap<>());
		labelsPerPage = Collections.synchronizedMap(new HashMap<>());
		offsetPerPage = Collections.synchronizedMap(new HashMap<>());
	}
	
	/**
	 * remove information relative to a specific page
	 * @param pageName
	 */
	private void resetPageInformation(String pageName) {
		fieldsPerPage.remove(pageName);
		labelsPerPage.remove(pageName);
		offsetPerPage.remove(pageName);
	}
	
	public ScreenshotUtil getScreenshotUtil() {
		return new ScreenshotUtil();
	}

	/**
	 * Check search criteria has the required information
	 */
	private void checkElementToSearch() {
		if (by.getType() == null) {
			throw new ConfigurationException("Element type is mandatory to search a field");
		} else if (by.getLeftOf() == null && by.getRightOf() == null && by.getAbove() == null && by.getBelow() == null && by.getText() == null) {
			throw new ConfigurationException("At least one of 'above', 'below', 'rightOf', 'leftOf', 'text' must be defined");
		}
	}

	public void findElement() {

		LocalDateTime start = LocalDateTime.now();
		
		checkElementToSearch();
		
		if (resetSearch) {
			resetPageInformation(origin);
		}
		
		// search fields if we do not have one for this page
		if (!fieldsPerPage.containsKey(origin)) {
			ScreenShot screenshotFile = getScreenshotFile();
			if (screenshotFile == null) {
				throw new ScreenshotException("Screenshot does not exist");
			}
			
			// TODO: handle other cases than browser
			// try to find viewport position so that we can match a position on browser capture with the same position on screen
			// we assume that browser is started on main screen in a multi-screen environment
			Rectangle viewportPosition = detectViewPortPosition(screenshotFile.getImage().getFile());
			offsetPerPage.put(origin, new Point(viewportPosition.x, viewportPosition.y));
			
			JSONObject snapshotDetectionData = SeleniumRobotSnapshotServerConnector.getInstance().detectFieldsInPicture(screenshotFile);
			List fields = Field.fromDetectionData(snapshotDetectionData);
			for (Field field: fields) {
				field.changePosition(viewportPosition.x, viewportPosition.y);
			}
			fieldsPerPage.put(origin, fields);
			
			List




© 2015 - 2025 Weber Informatics LLC | Privacy Policy