/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 bvt.gui;

import static org.junit.Assert.*;
import static org.openoffice.test.common.Testspace.*;
import static org.openoffice.test.vcl.Tester.*;
import static testlib.gui.AppTool.*;
import static testlib.gui.UIMap.*;

import java.awt.Rectangle;
import java.io.File;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.openoffice.test.common.FileUtil;
import org.openoffice.test.common.GraphicsUtil;
import org.openoffice.test.common.Logger;

import testlib.gui.SCTool;

/**
 *
 */
public class BasicFunctionTest {

	@Rule
	public Logger log = Logger.getLogger(this);

	@BeforeClass
	public static void beforeClass() {
		app.clean();
	}

	@AfterClass
	public static void afterClass() {
		app.stop();
	}

	@Before
	public void before() {
		app.stop();
		app.start();
	}


	@Test
	public void smokeTest() {
		File smoketestOutput = new File(aoo.getUserInstallation(), "user/temp");
		File testDir = getFile().getParentFile();
		File smokeTestDir = new File(testDir, "smoketestdoc");
		File smokeTestTargetDir = new File(smokeTestDir, "target");
		prepareData(new File(smokeTestTargetDir, "TestExtension.oxt").getAbsolutePath());
		// Open sample file smoketestdoc.sxw
		open(prepareData(new File(smokeTestTargetDir, "smoketestdoc.odt").getAbsolutePath()));
		writer.waitForEnabled(10, 2);
		// Run test cases
		app.dispatch("vnd.sun.star.script:Standard.Global.StartTestWithDefaultOptions?language=Basic&location=document", 120);
		String smoketestlog = FileUtil.readFileAsString(new File(smoketestOutput, "smoketest.log"));
		String testclosurelog = FileUtil.readFileAsString(new File(smoketestOutput, "testclosure.log"));
		log.info(smoketestlog + "\n" + testclosurelog);
		assertTrue("No Error", !smoketestlog.contains("error") && !testclosurelog.contains("error"));

	}

	@Test
	public void testExportAsPDF() throws Exception {
		String file = prepareData("bvt/pdf.odt");
		String exportTo1 = getPath("temp/1.pdf");
		String exportTo2 = getPath("temp/2.pdf");
		deleteFile(exportTo1);
		deleteFile(exportTo2);
		open(file);
		writer.waitForExistence(10, 1);
		app.dispatch(".uno:ExportToPDF");
		pdfGeneralPage.ok();
		submitSaveDlg(exportTo1);
		sleep(1);
		String magic = FileUtil.readFileAsString(exportTo1).substring(0, 4);
		assertEquals("PDF is exported?", "%PDF", magic);

		button(".uno:ExportDirectToPDF").click();//Click via toolbar
		submitSaveDlg(exportTo2);
		sleep(1);
		magic = FileUtil.readFileAsString(exportTo2).substring(0, 4);
		assertEquals("PDF is exported directly?", "%PDF", magic);
	}

	/**
	 * Test the File -- Print Dialog show
	 *
	 */
	@Test
	public void testPrinter() {
		// Create a new text document
		newTextDocument();
		app.dispatch(".uno:PrinterSetup");
		if (activeMsgBox.exists(2))
			activeMsgBox.ok();

//		PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
//		String[] names = new String[ps.length];
//		for (int i = 0; i < ps.length; i++) {
//			names[i] = ps[i].getName();
//		}
//
//		assertArrayEquals("Printers Names", names, printerSetUpDlgPrinterNames.getItemsText());
		assertTrue("Printer Setup dialog appears", printerSetUpDlg.exists(3));
		printerSetUpDlg.cancel();
	}

	/**
	 * Test the File -- Java Dialog show
	 *
	 */
//	@Test
//	public void testJavaDialog() {
//
//		// Create a new text document and launch a Wizards dialog which need JVM
//		// work correctly.
//		app.dispatch("private:factory/swriter");
//		File tempfile = new File(oo.getUserInstallation(), "user/template/myAgendaTemplate.ott");
//		FileUtil.deleteFile(tempfile);
//		sleep(3);
//		app.dispatch("service:com.sun.star.wizards.agenda.CallWizard?start");
//		sleep(5);
//		assertTrue(Wizards_AgendaDialog.exists(10));
//		Wizards_AgendaDialog_FinishButton.click();
//		sleep(10);
//		writer.focus();
//		sleep(1);
//		app.dispatch(".uno:SelectAll");
//		typeKeys("<$copy>");
//		// System.out.println("now txt:"+app.getClipboard());
//		// assertTrue(app.getClipboard().startsWith("<Name>"));
//		assertNotNull(app.getClipboard());
//	}

	/**
	 * Test the Tools / Macros / Organize Dialogs" show
	 *
	 */
	@Test
	public void testRunMacro() {
		open(prepareData("bvt/macro.ods"));
		calc.waitForExistence(10, 2);
		app.dispatch(".uno:RunMacro");
		runMacroDlgCategories.expand("macro.ods");
		runMacroDlgCategories.expand("Standard");
		runMacroDlgCategories.select("Module1");
		runMacroDlgCommands.select(0);
		runMacroDlg.ok();
		sleep(1);
		assertEquals("A3 should be =1+3", "4", SCTool.getCellText("A3"));
		discard();
	}

	/**
	 * Test the About Dialog show
	 *
	 */
	@Test
	public void testHelp() {
		app.dispatch(".uno:About");
		assertTrue(aboutDialog.exists(5));
		aboutDialog.ok();
		sleep(1);
		typeKeys("<F1>");
		assertTrue(helpWindow.exists(5));
		helpWindow.close();
	}

	/**
	 * Test inserting a picture in text document
	 *
	 * @throws Exception
	 */

	@Test
	public void testInsertPictureInDocument() throws Exception {
		String bmp_green = prepareData("image/green_256x256.bmp");
		String bmp_red = prepareData("image/red_256x256.bmp");

		// Create a new text document
		newTextDocument();
		// Insert a picture fully filled with green
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_green);
		writer.click(5,200);
		sleep(1);

		// Verify if the picture is inserted successfully
		Rectangle rectangle = GraphicsUtil.findRectangle(writer.getScreenRectangle(), 0xFF00FF00);
		assertTrue("Green Picture is inserted?" + rectangle, rectangle != null && rectangle.getWidth() > 10);
		// insert another picture
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_red);
		writer.click(5, 200);
		sleep(1);
		// Verify if the picture is inserted successfully
		rectangle = GraphicsUtil.findRectangle(writer.getScreenRectangle(), 0xFFFF0000);
		assertTrue("Green Picture is inserted? " + rectangle, rectangle != null && rectangle.getWidth() > 10);
		discard();
	}

	@Test
	public void testInsertPictureInSpreadsheet() throws Exception {
		String bmp_green = prepareData("image/green_64x64.png");
		String bmp_red = prepareData("image/red_64x64.png");
		newSpreadsheet();
		// Insert a picture fully filled with green
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_green);
		calc.click(5, 150);
		sleep(1);

		// Verify if the picture is inserted successfully
		Rectangle rectangle = GraphicsUtil.findRectangle(calc.getScreenRectangle(), 0xFF00FF00);
		assertTrue("Green Picture is inserted?" + rectangle, rectangle != null && rectangle.getWidth() > 10);

		SCTool.selectRange("C1");
		// insert another picture
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_red);
		calc.click(5, 150);
		sleep(1);
		// Verify if the picture is inserted successfully
		rectangle = GraphicsUtil.findRectangle(calc.getScreenRectangle(), 0xFFFF0000);
		assertTrue("Red Picture is inserted? " + rectangle, rectangle != null && rectangle.getWidth() > 10);
		discard();
	}

	@Test
	public void testInsertPictureInPresentation() throws Exception {
		String bmp_green = prepareData("image/green_256x256.bmp");
		String bmp_red = prepareData("image/red_256x256.bmp");
		newPresentation();
		// Insert a picture fully filled with green
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_green);
		impress.click(5, 5);
		sleep(1);

		// Verify if the picture is inserted successfully
		Rectangle rectangle = GraphicsUtil.findRectangle(impress.getScreenRectangle(), 0xFF00FF00);
		assertTrue("Green Picture is inserted?" + rectangle, rectangle != null && rectangle.getWidth() > 10);
		// insert another picture
		app.dispatch(".uno:InsertGraphic");
		submitOpenDlg(bmp_red);
		impress.click(1, 1);
		sleep(1);
		// Verify if the picture is inserted successfully
		rectangle = GraphicsUtil.findRectangle(impress.getScreenRectangle(), 0xFFFF0000);
		assertTrue("Red Picture is inserted? " + rectangle, rectangle != null && rectangle.getWidth() > 10);
		discard();
	}

	@Test
	public void testSlideShow() throws Exception {
		open(prepareData("bvt/slideshow.odp"));
		impress.waitForExistence(10, 2);
		sleep(1);
		impress.typeKeys("<F5>");
		sleep(3);
		Rectangle rectangle = GraphicsUtil.findRectangle(slideShow.getScreenRectangle(), 0xFFFF0000);
		assertNotNull("1st slide appears", rectangle);
		slideShow.click(0.5, 0.5);
		sleep(2);
		rectangle = GraphicsUtil.findRectangle(slideShow.getScreenRectangle(), 0xFF00FF00);
		assertNotNull("2nd slide appears", rectangle);
		typeKeys("<enter>");
		sleep(2);
		rectangle = GraphicsUtil.findRectangle(slideShow.getScreenRectangle(), 0xFF0000FF);
		assertNotNull("3rd slide appears", rectangle);
		slideShow.click(0.5, 0.5);
		sleep(2);
		rectangle = GraphicsUtil.findRectangle(slideShow.getScreenRectangle(), 0xFF0000FF);
		assertNull("The end", rectangle);
		slideShow.click(0.5, 0.5);
		sleep(3);
		assertFalse("Quit", slideShow.exists());
	}

	@Test
	public void testFind() {
		open(prepareData("bvt/find.odt"));
		writer.waitForExistence(10, 2);
		app.dispatch(".uno:SearchDialog");
		findDlgFor.setText("OpenOffice");
		findDlgFind.click();
		sleep(1);
		writer.typeKeys("<$copy>");
		assertEquals("OpenOffice", app.getClipboard());
		findDlgFindAll.click();
		sleep(1);
		writer.typeKeys("<$copy>");
		assertEquals("OpenOfficeOpenOfficeOpenOffice", app.getClipboard());
		findDlgReplaceWith.setText("Awesome OpenOffice");
		findDlgReplaceAll.click();
		sleep(1);
		msgbox("Search key replaced 3 times.").ok();
		findDlg.close();
		sleep(1);
		assertEquals(
				"Apache Awesome OpenOffice is comprised of six personal productivity applications: a word processor (and its web-authoring component), spreadsheet, presentation graphics, drawing, equation editor, and database. Awesome OpenOffice is released on Windows, Solaris, Linux and Macintosh operation systems, with more communities joining, including a mature FreeBSD port. Awesome OpenOffice is localized, supporting over 110 languages worldwide. ",
				copyAll());
		discard();
	}

	@Test
	public void testFindFormulasAndValues() {
		open(prepareData("bvt/searchFormulasValues.ods"));
		calc.waitForExistence(10, 2);

		// Searching for 2003 by formula finds A2
		SCTool.selectRange("A1");
		app.dispatch(".uno:SearchDialog");
		findDlgFor.setText("2003");
		findDlgMore.click();
		findDlgCalcSearchIn.select("Formulas");
		findDlgFind.click();
		sleep(1);
		assertEquals("wrong cell found for formulas search", "A2", scInputBarPosition.getText());
		findDlg.close();

		// Searching for October by value finds A2
		SCTool.selectRange("A1");
		app.dispatch(".uno:SearchDialog");
		findDlgFor.setText("October");
		findDlgMore.click();
		findDlgCalcSearchIn.select("Values");
		findDlgFind.click();
		sleep(1);
		assertEquals("wrong cell found for values search", "A2", scInputBarPosition.getText());
		findDlg.close();

		discard();
	}

	@Test
	public void testFillInSpreadsheet() {
		String[][] expected1 = new String[][] { { "1" }, { "1" }, { "1" }, { "1" }, { "1" }, { "1" }, };
		String[][] expected2 = new String[][] { { "2" }, { "2" }, { "2" }, { "2" }, { "2" }, { "2" }, };
		String[][] expected3 = new String[][] { { "Hi friends", "Hi friends", "Hi friends", "Hi friends" } };
		String[][] expected4 = new String[][] { { "99999.999", "99999.999", "99999.999", "99999.999" } };
		String[][] expected5 = new String[][] {
		{ "99999.999", "-10" }, { "100000.999", "-9" }, { "100001.999", "-8" }, { "100002.999", "-7" }, { "100003.999", "-6" }
		};
		newSpreadsheet();
		SCTool.selectRange("C5");
		typeKeys("1<enter>");
		SCTool.selectRange("C5:C10");
		app.dispatch(".uno:FillDown");
		assertArrayEquals("Fill Down:", expected1, SCTool.getCellTexts("C5:C10"));

		SCTool.selectRange("D10");
		typeKeys("2<enter>");
		SCTool.selectRange("D5:D10");
		app.dispatch(".uno:FillUp");
		assertArrayEquals("Fill Up:", expected2, SCTool.getCellTexts("D5:D10"));

		SCTool.selectRange("A1");
		typeKeys("Hi friends<enter>");
		SCTool.selectRange("A1:D1");
		app.dispatch(".uno:FillRight");
		assertArrayEquals("Fill Right:", expected3, SCTool.getCellTexts("A1:D1"));

		SCTool.selectRange("D2");
		typeKeys("99999.999<enter>");
		SCTool.selectRange("A2:D2");
		app.dispatch(".uno:FillLeft");
		assertArrayEquals("Fill left:", expected4, SCTool.getCellTexts("A2:D2"));

		SCTool.selectRange("E1");
		typeKeys("99999.999<tab>-10<enter>");

		SCTool.selectRange("E1:F5");
		app.dispatch(".uno:FillSeries");
		fillSeriesDlg.ok();
		sleep(1);
		assertArrayEquals("Fill series..", expected5, SCTool.getCellTexts("E1:F5"));
		discard();
	}

	@Test
	public void testSort() {
		String[][] expected1 = new String[][] { { "-9999999" }, { "-1.1" }, { "-1.1" }, { "0" }, { "0" }, { "0.1" }, { "10" }, { "12" }, { "9999999" }, { "9999999" },

		};
		String[][] expected2 = new String[][] { { "TRUE", "Oracle" }, { "TRUE", "OpenOffice" }, { "FALSE", "OpenOffice" }, { "TRUE", "IBM" }, { "FALSE", "IBM" },
				{ "TRUE", "Google" }, { "FALSE", "facebook " }, { "TRUE", "Apache" }, { "TRUE", "!yahoo" }, { "TRUE", "" },

		};

		String[][] expected3 = new String[][] { { "Sunday" }, { "Monday" }, { "Tuesday" }, { "Wednesday" }, { "Thursday" }, { "Friday" }, { "Saturday" },

		};

		String[][] expected4 = new String[][] { { "-$10.00" }, { "$0.00" }, { "$0.00" }, { "$1.00" }, { "$3.00" }, { "$9.00" }, { "$123.00" }, { "$200.00" }, { "$400.00" },
				{ "$10,000.00" },

		};
		open(prepareData("bvt/sort.ods"));
		calc.waitForExistence(10, 2);
		SCTool.selectRange("A1:A10");
		app.dispatch(".uno:DataSort");
		sortWarningDlgCurrent.click();
		assertEquals(1, sortPageBy1.getSelIndex());
		sortPage.ok();
		sleep(1);
		assertArrayEquals("Sorted Data", expected1, SCTool.getCellTexts("A1:A10"));
		SCTool.selectRange("B1:C10");
		app.dispatch(".uno:DataSort");

		sortPageBy1.select(2);
		sortPageDescending1.check();
		assertFalse(sortPageBy3.isEnabled());
		assertFalse(sortPageAscending3.isEnabled());
		assertFalse(sortPageDescending3.isEnabled());
		sortPageBy2.select(1);
		assertTrue(sortPageBy3.isEnabled());
		assertTrue(sortPageAscending3.isEnabled());
		assertTrue(sortPageDescending3.isEnabled());
		sortPageDescending2.check();
		sortPageBy2.select(0);
		assertFalse(sortPageBy3.isEnabled());
		assertFalse(sortPageAscending3.isEnabled());
		assertFalse(sortPageDescending3.isEnabled());
		sortPageBy2.select(1);
		sortPage.ok();
		sleep(1);

		assertArrayEquals("Sorted Data", expected2, SCTool.getCellTexts("B1:C10"));
		SCTool.selectRange("D1:D7");
		app.dispatch(".uno:DataSort");
		sortWarningDlgCurrent.click();
		sortOptionsPage.select();
		sortOptionsPageRangeContainsColumnLabels.uncheck();
		sortOptionsPageCustomSortOrder.check();
		sortOptionsPageCustomSortOrderList.select("Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday");
		sortOptionsPage.ok();
		sleep(1);
		assertArrayEquals("Sorted Data", expected3, SCTool.getCellTexts("D1:D7"));

		SCTool.selectRange("E1:E10");
		app.dispatch(".uno:DataSort");
		sortWarningDlgCurrent.click();
		sortPage.ok();
		sleep(1);
		assertArrayEquals("Sorted Data", expected4, SCTool.getCellTexts("E1:E10"));
		discard();
	}

	/**
	 * Test insert a chart in a draw document 1. New a draw document 2. Insert a
	 * chart 3. Check if the chart is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertChartInDraw() throws Exception {
		// Create a new drawing document
		newDrawing();
		// Insert a chart
		app.dispatch(".uno:InsertObjectChart");
		sleep(3);

		// Verify if the chart is inserted successfully
		assertTrue("Chart Editor appears", chart.exists(3));
		// Focus on edit pane
		draw.click(5, 5);
		sleep(1);
		assertFalse("Chart Editor appears", chart.exists());
		discard();
	}

	/**
	 * Test insert a chart in a text document 1. New a text document 2. Insert a
	 * chart 3. Check if the chart is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertChartInDocument() throws Exception {
		// Create a new text document
		newTextDocument();
		// Insert a chart
		app.dispatch(".uno:InsertObjectChart");
		sleep(3);

		// Verify if the chart is inserted successfully
		assertTrue("Chart Editor appears", chart.exists(3));
		// Focus on edit pane
		writer.click(5, 5);
		sleep(1);
		assertFalse("Chart Editor appears", chart.exists());
		discard();
	}

	/**
	 * Test insert a chart in a spreadsheet document 1. New a spreadsheet
	 * document 2. Insert a chart 3. Check if the chart is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertChartInSpreadsheet() throws Exception {
		// Create a new spreadsheet document
		newSpreadsheet();
		// Insert a chart
		app.dispatch(".uno:InsertObjectChart");
		sleep(3);
		chartWizard.ok();

		// Verify if the chart is inserted successfully
		assertTrue("Chart Editor appears", chart.exists(3));
		// Focus on edit pane
		calc.click(5, 5);
		sleep(1);
		assertFalse("Chart Editor appears", chart.exists());
		discard();
	}

	/**
	 * Test insert a chart in a presentation document 1. New a presentation
	 * document 2. Insert a chart 3. Check if the chart is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertChartInPresentation() throws Exception {
		// Create a new presentation document
		newPresentation();
		// Insert a chart
		app.dispatch(".uno:InsertObjectChart");
		sleep(3);
		// Verify if the chart is inserted successfully
		assertTrue("Chart Editor appears", chart.exists(3));
		// Focus on edit pane
		impress.click(5, 5);
		sleep(1);
		assertFalse("Chart Editor appears", chart.exists());
		discard();
	}

	/**
	 * Test insert a table in a draw document 1. New a draw document 2. Insert a
	 * default table 3. Check if the table is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertTableInDraw() throws Exception {
		// Create a new drawing document
		newDrawing();
		// Insert a table
		app.dispatch(".uno:InsertTable");
		insertTable.ok();
		sleep(1);
		draw.typeKeys("3");
		assertTrue("Table Toolbar appears", tableToolbar.exists(3));
//		assertEquals("The cell content", "3", copyAll());
		discard();
	}

	/**
	 * Test insert a table in a text document 1. New a text document 2. Insert a
	 * default table 3. Check if the table is inserted successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertTableInDocument() throws Exception {
		// Create a new text document
		newTextDocument();
		// Insert a table
		app.dispatch(".uno:InsertTable");
		writerInsertTable.ok();
		sleep(1);
		writer.typeKeys("3");
		// Verify if the table toolbar is active
		assertTrue("Table Toolbar appears", tableToolbar.exists(3));
//		assertEquals("The cell content", "3", copyAll());
		discard();
	}

	/**
	 * Test insert a table in a presentation document 1. New a presentation
	 * document 2. Insert a default table 3. Check if the table is inserted
	 * successfully
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertTableInPresentation() throws Exception {
		// Create a new presentation document
		newPresentation();

		// Insert a table
		app.dispatch(".uno:InsertTable");
		insertTable.ok();
		sleep(1);
		impress.typeKeys("3");
		assertTrue("Table Toolbar appears", tableToolbar.exists(3));
//		assertEquals("The cell content", "3", copyAll());
		discard();
	}

	/**
	 * Test insert a function in a spreadsheet document via Sum button 1. New a
	 * spreadsheet document 2. Insert a function via Sum button 3. Check if the
	 * result is correct
	 *
	 * @throws Exception
	 */
	@Test
	public void testSumInFormulaBar() throws Exception {
		// Create a new spreadsheet document
		newSpreadsheet();
		// Insert source numbers
		String sourceNumber1 = "5";
		String sourceNumber2 = "3";
		String expectedResult = "8";
		SCTool.selectRange("A1");
		typeKeys(sourceNumber1);
		SCTool.selectRange("B1");
		typeKeys(sourceNumber2);
		// Insert a function via Sum button
		SCTool.selectRange("C1");
		scInputBarSum.click();
		typeKeys("<enter>");
		// Verify if the calculated result is equal to the expected result
		assertEquals("The calculated result", expectedResult, SCTool.getCellText("C1"));
		discard();
	}

	/**
	 * Test insert a function in a spreadsheet document via inputbar 1. New a
	 * spreadsheet document 2. Insert a function via inputbar: COS 3. Check if
	 * the result is correct
	 *
	 * @throws Exception
	 */
	@Test
	public void testInsertFunctionViaFormulaBar() throws Exception {
		// Create a new spreadsheet document
		newSpreadsheet();
		// Insert source numbers and expected result
		String sourceData = "0";
		String expectedResult = "1";
		SCTool.selectRange("A1");
		typeKeys(sourceData);

		// Insert a function via inputbar: COS
		SCTool.selectRange("D1");
		scInputBarInput.inputKeys("=COS(A1)");
		typeKeys("<enter>");
		sleep(1);
		// Verify if the calculated result is equal to the expected result
		String result = SCTool.getCellText("D1");
		sleep(1);
		assertEquals("The calculated result", expectedResult, result);
		discard();
	}

	/**
	 * Test insert a function in a spreadsheet document via Function Wizard
	 * Dialog 1. New a spreadsheet document 2. Insert a function via Function
	 * Wizard Dialog: ABS 3. Check if the result is correct
	 *
	 * @throws Exception
	 */
	@Test
	public void testFunctionWizardInFormulaBar() throws Exception {
		// Create a new spreadsheet document
		newSpreadsheet();
		// Insert source number
		String sourceNumber = "-5";
		String expectedResult = "5";
		SCTool.selectRange("A1");
		typeKeys(sourceNumber);
		typeKeys("<enter>");
		// Insert a function via Function Wizard Dialog: ABS
		SCTool.selectRange("B1");
		app.dispatch(".uno:FunctionDialog");
		// SC_FunctionWizardDlg_FunctionList.doubleClick(5, 5);
		scFunctionWizardDlgFunctionList.select("ABS");
		scFunctionWizardDlgNext.click(); // Use "Next" button
		scFunctionWizardDlgEdit1.typeKeys("A1");
		sleep(1);
		scFunctionWizardDlg.ok();
		sleep(1);
		// Verify if the calculated result is equal to the expected result
		String result = SCTool.getCellText("B1");
		sleep(1);
		assertEquals("The calculated result", expectedResult, result);
		discard();
	}

	/**
	 * Test open a non-http(s) type hyperlink (with host only) in a text document.
	 * (coverage included in fvt.gui.sw.hyperlink.WarningDialog
	 * testHyperlinkDisplaysWarning() and included here for build verification)
	 * 1. New a text document
	 * 2. Insert a dav type hyperlink
	 * 3. Open hyperlink
	 * 4. Verify security warning dialog is displayed
	 *
	 * @throws Exception
	 */
	@Test
	public void testNonHttpHyperlinkWithHostOnly() throws Exception {
		// Create a new text document
		newTextDocument();
		writer.waitForExistence(10, 2);
		// open the hyperlink dialog
		writer.typeKeys("<alt i>"); // insert menu
		writer.typeKeys("h"); // hyperlink
		hyperlinkInetPathComboBox.setText("dav://nonexistant.url.com"); //target
		hyperlinkInetText.setText("dav://nonexistant.url.com"); // displayed text
		hyperlinkDialogOkBtn.click(); // apply
		hyperlinkDialogCancelBtn.click(); // close
		sleep(1); // give the dialog time to close
		typeKeys("<shift F10>"); // context menu
		typeKeys("o"); // open hyperlink
		// we can't be sure of the language so just check for the dialog
		boolean msgExists = activeMsgBox.exists(1); // wait 1 second for the dialog
		if (msgExists) {
			activeMsgBox.no(); // close dialog
		}
		assertTrue("security warning not displayed", msgExists);
		discard();
	}

}
