/*
Copyright 2011-2012 Opera Software ASA
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.opera.core.systems;
import com.google.common.collect.ImmutableList;
import com.opera.core.systems.model.ScreenCaptureReply;
import com.opera.core.systems.testing.Ignore;
import com.opera.core.systems.testing.OperaDriverTestCase;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.zip.Adler32;
import javax.imageio.ImageIO;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.openqa.selenium.Platform.MAC;
public class ScreenshotTest extends OperaDriverTestCase {
private OperaWebElement text;
private OperaWebElement radioLittle;
private OperaWebElement radioSome;
private OperaWebElement radioLots;
@Before
public void setup() {
driver.manage().timeouts().implicitlyWait(2500, TimeUnit.SECONDS);
driver.navigate().to(pages.test);
text = (OperaWebElement) driver.findElement(By.id("input_email"));
radioSome = (OperaWebElement) driver.findElement(By.id("radio_some"));
radioLittle = (OperaWebElement) driver.findElement(By.id("radio_little"));
radioLots = (OperaWebElement) driver.findElement(By.id("radio_lots"));
}
@After
public void resetImplicitWait() {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
}
@AfterClass
public static void tearDown() {
new File("one.png").delete();
new File("two.png").delete();
}
private static int digest(String filename) throws IOException {
FileInputStream fis = new FileInputStream(filename);
byte[] data = new byte[fis.available()];
int i = 0;
int c;
while ((c = fis.read()) != -1) {
data[i++] = (byte) c;
}
fis.close();
final Adler32 digester = new Adler32();
digester.update(data);
return (int) digester.getValue();
}
@Test
public void elementsMd5Same() {
String one = radioLittle.saveScreenshot("one.png");
String two = radioSome.saveScreenshot("two.png");
assertEquals(one, two);
}
@Test
public void writtenFilesSame() throws IOException {
String one = "one.png";
String two = "two.png";
radioLittle.saveScreenshot(one);
radioSome.saveScreenshot(two);
assertEquals(digest(one), digest(two));
}
@Test
public void elementsMd5NotSame() {
String one = radioLittle.saveScreenshot("one.png");
String two = radioLots.saveScreenshot("two.png");
assertNotSame(one, two);
}
@Test
public void writtenFilesNotSame() throws IOException {
String one = "one.png";
String two = "two.png";
radioLittle.saveScreenshot(one);
radioLots.saveScreenshot(two);
assertNotSame(digest(one), digest(two));
}
@Test
public void timeoutIsRespected() {
driver.navigate().to(pages.timer);
OperaWebElement text = (OperaWebElement) driver.findElement(By.id("one"));
String original = text.saveScreenshot("one.png");
String changed = text.saveScreenshot("two.png", 2000);
assertNotSame(original, changed);
}
@Test
public void hashesCanBeProvided() {
String md5 = text.saveScreenshot("one.png");
text.saveScreenshot("two.png", 0, true, ImmutableList.of(md5));
File one = new File("one.png");
File two = new File("two.png");
// Confirm that a png is not returned when the hash matches
Assert.assertNotSame(0, one.length());
assertEquals(0, two.length());
}
@Test
@Ignore(platforms = MAC, value = "Needs investigation, doesn't return anything")
public void realPng() {
ScreenCaptureReply reply = driver.captureScreen();
byte[] png = reply.getPng();
assertTrue("PNG magic bytes match",
png[0] == (byte) 0x89 &&
png[1] == (byte) 0x50 &&
png[2] == (byte) 0x4E &&
png[3] == (byte) 0x47 &&
png[4] == (byte) 0x0D &&
png[5] == (byte) 0x0A &&
png[6] == (byte) 0x1A &&
png[7] == (byte) 0x0A
);
}
/**
* Tests the captureScreen method that returns a ScreenCaptureReply
*/
@Test
public void expectsScreenshotReply() {
ScreenCaptureReply one = radioLittle.captureScreen();
ScreenCaptureReply two = radioSome.captureScreen();
assertEquals(one.getMd5(), two.getMd5());
assertTrue("PNG data is the same", Arrays.equals(one.getPng(), two.getPng()));
assertFalse(one.isBlank());
assertFalse(two.isBlank());
}
@Test
public void zeroHeight() {
// Shouldn't throw exceptions
driver.navigate().to(pages.zeroHeightStandards);
((OperaWebElement) driver.findElement(By.tagName("html"))).getImageHash();
driver.navigate().to(pages.zeroHeightQuirks);
((OperaWebElement) driver.findElement(By.tagName("html"))).getImageHash();
}
@Test
@Ignore("We don't support taking single element screenshots of plugins")
public void flash() {
driver.navigate().to(pages.flash);
OperaWebElement img = (OperaWebElement) driver.findElement(By.id("img_container"));
OperaWebElement flash = (OperaWebElement) driver.findElement(By.id("flash_container"));
String imgMD5 = img.saveScreenshot("one.png");
String flashMD5 = flash.saveScreenshot("two.png");
assertEquals(imgMD5, flashMD5);
}
@Test
public void takesScreenshot() throws IOException {
driver.navigate().to(pages.tall);
File file = driver.getScreenshotAs(OutputType.FILE);
BufferedImage img = ImageIO.read(file);
assertEquals(5100, img.getHeight());
// Check the top pixel
int botcol = img.getRGB(0, 0);
assertEquals(0xFF0000, botcol & 0xFFFFFF);
}
@Test
@Ignore("Opera problem: Areas outside current viewport are black")
public void fullScreenshot() throws IOException {
driver.navigate().to(pages.tall);
File file = driver.getScreenshotAs(OutputType.FILE);
BufferedImage img = ImageIO.read(file);
assertEquals(5100, img.getHeight());
// Make sure the bottom colour is green, not black.
int botcol = img.getRGB(0, 5050);
assertEquals(0xFF00, botcol & 0xFF00);
}
}