Katalon Studio - Image Comparison - Image Diff is not generated

Hi,

I am working on these scenarios:
Test Case 01 (PASSED):

WebUI.openBrowser('')

WebUI.navigateToUrl('https://bankmandiri.co.id/')

WebUI.maximizeWindow()

WebUI.click(findTestObject('Mandiri/Page_Bank Mandiri - Terdepan, Terpercaya, T_9dcea6/span_Bantuan'))

WebUI.verifyElementPresent(findTestObject('Mandiri/Page_Bantuan/h3_Bantuan  FAQ'), 5)

WebUI.takeFullPageScreenshot('C://Users//sugiarto//Screenshots//Baseline.png')

WebUI.closeBrowser()

Test Case 02 (FAILED):

WebUI.openBrowser('')

WebUI.navigateToUrl('https://bankmandiri.co.id/')

WebUI.maximizeWindow()

WebUI.click(findTestObject('Mandiri/Page_Bank Mandiri - Terdepan, Terpercaya, T_9dcea6/span_Bantuan'))

WebUI.verifyElementPresent(findTestObject('Mandiri/Page_Bantuan/h3_Bantuan  FAQ'), 5)

WebUI.click(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'))

WebUI.setText(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'), 'KATALON')

WebUI.takeFullPageScreenshot('C://Users//sugiarto//Screenshots//Compared.png')

String imgOriginal = 'C://Users//sugiarto//Screenshots//Baseline.png'

String imgToCompareWithOriginal = 'C://Users//sugiarto//Screenshots//Compared.png'

String imgOutputDifferences = 'C://Users//sugiarto//Screenshots//Different.png'

ImageComparison imageComparison = new ImageComparison(10, 10, 0.05)

if (imageComparison.fuzzyEqual(imgOriginal, imgToCompareWithOriginal, imgOutputDifferences)) {
	System.out.println('Images are fuzzy-equal.')
} else {
	System.out.println('Images are not fuzzy-equal.')
}

WebUI.closeBrowser()

The error is as follow:

Test Cases/VISUAL TEST/Mandiri Compare FAILED.
Reason:
java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/JPEGCodec
	at org.frontendtest.components.ImageComparison.saveImage(ImageComparison.java:160)
	at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:76)
	at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
	at org.frontendtest.components.ImageComparison$fuzzyEqual.call(Unknown Source)
	at Mandiri Compare.run(Mandiri Compare:58)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:442)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:433)
	at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:412)
	at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:404)
	at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:281)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:138)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:129)
	at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
	at TempTestCase1638511645362.run(TempTestCase1638511645362.groovy:25)
Caused by: java.lang.ClassNotFoundException: com.sun.image.codec.jpeg.JPEGCodec
	... 16 more

When I checked on the folder, the file Compared.png is generated properly but the file Different.png is not properly generated:
image

NOTE: the image comparison (ImageComparison is a jar) refers to this Selenium Screenshot Comparison in Java | FRET

What would be the problem?

@kazurayam Do you have any idea about my error:
Sorry I mention you :slight_smile:

Test Cases/VISUAL TEST/Mandiri Compare FAILED.
Reason:
java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/JPEGCodec
	at org.frontendtest.components.ImageComparison.saveImage(ImageComparison.java:160)
	at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:76)
	at org.frontendtest.components.ImageComparison.fuzzyEqual(ImageComparison.java:23)
	at org.frontendtest.components.ImageComparison$fuzzyEqual.call(Unknown Source)
	at Mandiri Compare.run(Mandiri Compare:58)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:442)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:433)
	at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:412)
	at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:404)
	at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:281)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:138)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:129)
	at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
	at TempTestCase1638511645362.run(TempTestCase1638511645362.groovy:25)
Caused by: java.lang.ClassNotFoundException: com.sun.image.codec.jpeg.JPEGCodec
	... 16 more

you have this.

possibly you need to change this to:

String imgOutputDifferences = 
    'C://Users//sugiarto//Screenshots//Different.jpg'

According to the source code at https://github.com/tholewebgods/image-comparison/blob/master/src/main/java/org/frontendtest/components/ImageComparison.java, the output must be in JPEG.

PNG is not supported.

I have changed to .jpg but still with the same error.
Let me check the link you provided.

This message proves that this library GitHub - tholewebgods/image-comparison: Java based image comparison library depends on com.sun.image.codec.jpeg.* class.

According to the information at

com/sun/image/codec/jpeg/JPEGCodec is only available in the old Sun’s JDK (possibly succeeded by Oracle JDK).

Katalon Studio does not use Sun/Oracle’s JDK. Therefore i suppose you can not use this library in Katalon Studio


The frontendtest’s ImageComparison class is designed to save the image into JPEG format. You are forced to use JPEG. This is the reason why it is dependent on the com/sun/image/codec/jpeg/JPEGCodec class, and therefore … does not work in Katalon Studio.

Other image comparison tools (such as AShot) does not force you to save the image into JPEG; you can save images in PNG. Therefore you will be be dependent on com/sun/image/codec/jpeg/JPEGCodec class; so your script would work.

1 Like

Thank you for the information.
Very much appreciate :slight_smile:

If you would like, I think, you can try to work around the Exception.

You can read the source;

You can see at the Line# 182

		try {
			ImageIO.write(bi, "jpeg", out);
		} catch (java.io.IOException io) {
			System.out.println("IOException while encoding the image: " + io);
		}

If you change this to

			ImageIO.write(bi, "png", out);

it will work in Katalon Studio without the Exception java.lang.NoClassDefFoundError: com/sun/image/codec/jpeg/JPEGCodec.

1 Like

Hi @kazurayam
I have resolved the issue by using Ashot and modify a bit of your Test Case here https://github.com/kazurayam/EntirePageScreenshotByAShotInKatalonStudio/blob/master/Scripts/TC4_imageDiffer/Script1535956206390.groovy

I created this test case and it works fine:

import my.AShotWrapper
import my.DevicePixelRatioResolver
import ru.yandex.qatools.ashot.Screenshot
import ru.yandex.qatools.ashot.comparison.ImageDiff
import ru.yandex.qatools.ashot.comparison.ImageDiffer

// resolve file name under the target directory
File resolveScreenshotFile(String fileName) {
	Path projectDir = Paths.get(RunConfiguration.getProjectDir())
	Path reportDir = projectDir.resolve('Screenshots')
	Files.createDirectories(reportDir)
	Path pngFile = reportDir.resolve(fileName)
	return pngFile.toFile()
}

// get diff%
Double diffRatioPercent(ImageDiff diff) {
	boolean hasDiff = diff.hasDiff()
	if (!hasDiff) {
		return 0.0
	}
	int diffSize = diff.getDiffSize()
	int area = diff.getMarkedImage().getWidth() * diff.getMarkedImage().getHeight()
	Double diffRatio = diff.getDiffSize() / area * 100
	return diffRatio
}

// ---------------------------------------------------------------------------------

WebUI.openBrowser('')

WebUI.navigateToUrl('https://bankmandiri.co.id/')

WebUI.maximizeWindow()

WebUI.click(findTestObject('Mandiri/Page_Bank Mandiri - Terdepan, Terpercaya, T_9dcea6/span_Bantuan'))

WebUI.verifyElementPresent(findTestObject('Mandiri/Page_Bantuan/h3_Bantuan  FAQ'), 5)

WebUI.click(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'))

WebUI.setText(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'), 'KATALON')

WebUI.takeFullPageScreenshot('C://Users//sugiarto//Katalon Studio//SUGIARTO//Screenshots//Compared.jpg')

// make AShot's ImageDiff
BufferedImage expectedImage = ImageIO.read(new File ("C://Users//sugiarto//Katalon Studio//SUGIARTO//Screenshots//Baseline.jpg"))
BufferedImage actualImage   = ImageIO.read(new File ("C://Users//sugiarto//Katalon Studio//SUGIARTO//Screenshots//Compared.jpg"))
Screenshot expectedScreenshot = new Screenshot(expectedImage)
Screenshot actualScreenshot = new Screenshot(actualImage)

ImageDiff diff = new ImageDiffer().makeDiff(expectedScreenshot, actualScreenshot)

BufferedImage markedImage = diff.getMarkedImage()

DecimalFormat dformat = new DecimalFormat("##0.00")

// check how much difference found between the original and the mimic.
// if diff% exceed the criteria, then mark the test case FAILED
Double criteriaPercent = 3.0
Double diffRatioPercent = diffRatioPercent(diff)
if (diffRatioPercent > criteriaPercent) {
	KeywordUtil.markFailed("diffRatio=${dformat.format(diffRatioPercent)} exceeds criteria=${criteriaPercent}")
}

// save the diff image into file
File diffFile = resolveScreenshotFile("Different.png")
ImageIO.write(markedImage, "PNG", diffFile)
WebUI.comment(">>> wrote the ImageDiff into ${diffFile.toString()}")

WebUI.closeBrowser()

Let me tell a bit of critics to your code.

  1. Absolute file path as string constant causes portability problem
WebUI.takeFullPageScreenshot('C://Users//sugiarto//Katalon Studio//SUGIARTO//Screenshots//Compared.jpg')

You wrote a string literal C://Users//sugiarto//Katalon Studio//SUGIARTO. This makes your code un-portable. This code will never run on any PC other than your own. You should always avoid writing absolute file paths for better portability.

How to? You already know it. See

File resolveScreenshotFile(String fileName) {
	Path projectDir = Paths.get(RunConfiguration.getProjectDir())
	Path reportDir = projectDir.resolve('Screenshots')
	Files.createDirectories(reportDir)

Why don’t you use this function as follows:

WebUI.takeFullPageScreenshot(resolveScreenshotFile('Compared.jpg').toString())
  1. JPG or PNG, which format do you want?

You named the files with .jpg extension.

BufferedImage expectedImage = ImageIO.read(new File (
    "... Screenshots//Baseline.jpg"))

But you actually made a PNG file:

ImageIO.write(markedImage, "PNG", diffFile)

Very confusing, isn’t it?

1 Like

Thanks a lot for the critics :slight_smile:
will tidy up the scripts.

Tidy it up :slight_smile:

import my.AShotWrapper
import my.DevicePixelRatioResolver
import ru.yandex.qatools.ashot.Screenshot
import ru.yandex.qatools.ashot.comparison.ImageDiff
import ru.yandex.qatools.ashot.comparison.ImageDiffer

// resolve file name under the target directory
File resolveScreenshotFile(String fileName) {
	Path projectDir = Paths.get(RunConfiguration.getProjectDir())
	Path reportDir = projectDir.resolve('Screenshots')
	Files.createDirectories(reportDir)
	Path pngFile = reportDir.resolve(fileName)
	return pngFile.toFile()
}

// get diff%
Double diffRatioPercent(ImageDiff diff) {
	boolean hasDiff = diff.hasDiff()
	if (!hasDiff) {
		return 0.0
	}
	int diffSize = diff.getDiffSize()
	int area = diff.getMarkedImage().getWidth() * diff.getMarkedImage().getHeight()
	Double diffRatio = diff.getDiffSize() / area * 100
	return diffRatio
}

// ---------------------------------------------------------------------------------

WebUI.openBrowser('')

WebUI.navigateToUrl('https://bankmandiri.co.id/')

WebUI.maximizeWindow()

WebUI.click(findTestObject('Mandiri/Page_Bank Mandiri - Terdepan, Terpercaya, T_9dcea6/span_Bantuan'))

WebUI.verifyElementPresent(findTestObject('Mandiri/Page_Bantuan/h3_Bantuan  FAQ'), 5)

WebUI.click(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'))

WebUI.setText(findTestObject('Mandiri/Page_Bantuan/input_Mandiri Search Portlet__Mandiri_Searc_fe9aca'), 'KATALON')

WebUI.takeFullPageScreenshot(resolveScreenshotFile('Compared.png').toString())

// make AShot's ImageDiff
BufferedImage expectedImage = ImageIO.read(resolveScreenshotFile('Baseline.png'))
BufferedImage actualImage   = ImageIO.read(resolveScreenshotFile('Compared.png'))
Screenshot expectedScreenshot = new Screenshot(expectedImage)
Screenshot actualScreenshot = new Screenshot(actualImage)

ImageDiff diff = new ImageDiffer().makeDiff(expectedScreenshot, actualScreenshot)

BufferedImage markedImage = diff.getMarkedImage()

DecimalFormat dformat = new DecimalFormat("##0.00")

// check how much difference found between the original and the mimic.
// if diff% exceed the criteria, then mark the test case FAILED
Double criteriaPercent = 30.0
Double diffRatioPercent = diffRatioPercent(diff)
if (diffRatioPercent > criteriaPercent) {
	KeywordUtil.markFailed("diffRatio=${dformat.format(diffRatioPercent)} exceeds criteria=${criteriaPercent}")
}

// save the diff image into file
File diffFile = resolveScreenshotFile("Different.png")
ImageIO.write(markedImage, "PNG", diffFile)
WebUI.comment(">>> wrote the ImageDiff into ${diffFile.toString()}")

WebUI.closeBrowser()