/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Jeanderson Candido <http://jeandersonbc.github.io> - Bug 444070
*******************************************************************************/
package org.eclipse.ui.tests.harness.util;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.tests.internal.util.VerifyDialog;
import junit.framework.Assert;
/**
* A <code>DialogCheck</code> is used test a dialog in
* various ways.
* <p>
* For interactive tests use <code>assertDialog</code>.
* For automated tests use <code>assert DialogTexts</code>.
* </p>
*/
public class DialogCheck {
private DialogCheck() {
}
private static VerifyDialog _verifyDialog;
/**
* Asserts that a given dialog is not null and that it passes certain visual
* tests. These tests will be verified manually by the tester using an input
* dialog. Use this assert method to verify a dialog's sizing, initial focus, or
* accessibility. To ensure that both the input dialog and the test dialog are
* accessible by the tester, the getShell() method should be used when creating
* the test dialog.
*
* Example usage:
* <code>Dialog dialog = new AboutDialog( DialogCheck.getShell() );
* DialogCheck.assertDialog(dialog, this);</code>
*
* @param dialog
* the test dialog to be verified.
* @param assertion
* this is the test case object, assertions will be executed on this
* object.
*
* @deprecated The <code>junit.framework.Assert</code> parameter is not used at
* all. Use {@link #assertDialog(Dialog) assertDialog(Dialog)}
* method.
*/
@Deprecated
public static void assertDialog(Dialog dialog, Assert assertion) {
assertNotNull(dialog);
if (_verifyDialog.getShell() == null) {
// force the creation of the verify dialog
getShell();
}
if (_verifyDialog.open(dialog) == IDialogConstants.NO_ID) {
assertTrue(_verifyDialog.getFailureText(), false);
}
}
/**
* Asserts that a given dialog is not null and that it passes certain visual
* tests. These tests will be verified manually by the tester using an input
* dialog. Use this assert method to verify a dialog's sizing, initial focus, or
* accessibility. To ensure that both the input dialog and the test dialog are
* accessible by the tester, the getShell() method should be used when creating
* the test dialog.
*
* Example usage:
* <code>Dialog dialog = new AboutDialog( DialogCheck.getShell() );
* DialogCheck.assertDialog(dialog);</code>
*
* @param dialog
* the test dialog to be verified.
*/
public static void assertDialog(Dialog dialog) {
assertNotNull(dialog);
if (_verifyDialog.getShell() == null) {
//force the creation of the verify dialog
getShell();
}
if (_verifyDialog.open(dialog) == IDialogConstants.NO_ID) {
assertTrue(_verifyDialog.getFailureText(), false);
}
}
/**
* Automated test that checks all the labels and buttons of a dialog to make
* sure there is enough room to display all the text. Any text that wraps is
* only approximated and is currently not accurate.
*
* @param dialog
* the test dialog to be verified.
* @param assertion
* this is the test case object, assertions will be executed on this
* object.
* @deprecated The <code>junit.framework.Assert</code> parameter is not used at
* all. Use {@link #assertDialogTexts(Dialog)
* assertDialogTexts(Dialog)} method.
*/
@Deprecated
public static void assertDialogTexts(Dialog dialog, Assert assertion) {
assertNotNull(dialog);
dialog.setBlockOnOpen(false);
dialog.open();
Shell shell = dialog.getShell();
verifyCompositeText(shell);
dialog.close();
// close "verify results" dialog, it makes other tests unhappy
_verifyDialog.buttonPressed(IDialogConstants.YES_ID);
}
/**
* Automated test that checks all the labels and buttons of a dialog to make
* sure there is enough room to display all the text. Any text that wraps is
* only approximated and is currently not accurate.
*
* @param dialog
* the test dialog to be verified.
* @param assertion
* this is the test case object, assertions will be executed on this
* object.
*/
public static void assertDialogTexts(Dialog dialog) {
assertNotNull(dialog);
dialog.setBlockOnOpen(false);
dialog.open();
Shell shell = dialog.getShell();
verifyCompositeText(shell);
dialog.close();
// close "verify results" dialog, it makes other tests unhappy
_verifyDialog.buttonPressed(IDialogConstants.YES_ID);
}
/**
* This method should be called when creating dialogs to test. This
* ensures that the dialog's parent shell will be that of the
* verification dialog.
*
* @return Shell The shell of the verification dialog to be used as
* the parent shell of the test dialog.
*/
public static Shell getShell() {
Shell shell = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getShell();
_verifyDialog = new VerifyDialog(shell);
_verifyDialog.create();
return _verifyDialog.getShell();
}
/*
* Looks at all the child widgets of a given composite and
* verifies the text on all labels and widgets.
* @param composite The composite to look through
*/
private static void verifyCompositeText(Composite composite) {
Control children[] = composite.getChildren();
for (Control child : children) {
if (child instanceof TabFolder) {
TabFolder folder = (TabFolder) child;
int numPages = folder.getItemCount();
for (int j = 0; j < numPages; j++) {
folder.setSelection(j);
}
}
else if (child instanceof Button) {
//verify the text if the child is a button
verifyButtonText((Button) child);
}
else if (child instanceof Label) {
//child is not a button, maybe a label
verifyLabelText((Label) child);
}
else if (child instanceof Composite) {
//child is not a label, make a recursive call if it is a composite
verifyCompositeText((Composite) child);
}
}
}
/*
* Verifies that a given button is large enough to display its text.
* @param button The button to verify,
*/
private static void verifyButtonText(Button button) {
String widget = button.toString();
Point size = button.getSize();
//compute the size with no line wrapping
Point preferred = button.computeSize(SWT.DEFAULT, SWT.DEFAULT);
//if (size.y/preferred.y) == X, then label spans X lines, so divide
//the calculated value of preferred.x by X
if (preferred.y * size.y > 0) {
preferred.y /= countLines(button.getText()); //check for '\n\'
if (size.y / preferred.y > 1) {
preferred.x /= (size.y / preferred.y);
}
}
String message = new StringBuffer("Warning: ").append(widget).append(
"\n\tActual Width -> ").append(size.x).append(
"\n\tRecommended Width -> ").append(preferred.x).toString();
if (preferred.x > size.x) {
//close the dialog
button.getShell().dispose();
assertTrue(message.toString(), false);
}
}
/*
* Verifies that a given label is large enough to display its text.
* @param label The label to verify,
*/
private static void verifyLabelText(Label label) {
if (!label.isVisible())
return;
String widget = label.toString();
Point size = label.getSize();
String labelText = label.getText();
if (labelText == null || labelText.length() == 0)
return;
//compute the size with no line wrapping
Point preferred = label.computeSize(SWT.DEFAULT, SWT.DEFAULT);
//if (size.y/preferred.y) == X, then label spans X lines, so divide
//the calculated value of preferred.x by X
if (preferred.y * size.y > 0) {
preferred.y /= countLines(label.getText());
if (size.y / preferred.y > 1) {
preferred.x /= (size.y / preferred.y);
}
}
String message = new StringBuffer("Warning: ").append(widget).append(
"\n\tActual Width -> ").append(size.x).append(
"\n\tRecommended Width -> ").append(preferred.x).toString();
if (preferred.x > size.x) {
//close the dialog
label.getShell().dispose();
assertTrue(message.toString(), false);
}
}
/*
* Counts the number of lines in a given String.
* For example, if a string contains one (1) newline character,
* a value of two (2) would be returned.
* @param text The string to look through.
* @return int the number of lines in text.
*/
private static int countLines(String text) {
int newLines = 1;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '\n') {
newLines++;
}
}
return newLines;
}
}