1 /* 2 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 */ 5 package javafx.scene.control.test.richtexteditor; 6 7 import client.test.Keywords; 8 import client.test.ScreenshotCheck; 9 import client.test.Smoke; 10 import java.awt.Toolkit; 11 import java.io.*; 12 import java.net.URL; 13 import java.util.*; 14 import java.util.Map.Entry; 15 import javafx.beans.property.SimpleStringProperty; 16 import javafx.scene.Node; 17 import javafx.scene.Scene; 18 import javafx.scene.control.*; 19 import javafx.scene.control.test.ControlsTestBase; 20 import javafx.scene.control.test.MenuApp; 21 import javafx.scene.control.test.RichTextEditorApp; 22 import javafx.scene.input.Clipboard; 23 import javafx.scene.web.HTMLEditor; 24 import javafx.scene.web.WebView; 25 import javafx.stage.PopupWindow; 26 import org.jemmy.action.GetAction; 27 import org.jemmy.control.Wrap; 28 import org.jemmy.env.Timeout; 29 import org.jemmy.fx.ByID; 30 import org.jemmy.fx.ByWindowType; 31 import org.jemmy.fx.Root; 32 import org.jemmy.fx.control.TextControlWrap; 33 import org.jemmy.fx.control.ThemeDriverFactory; 34 import org.jemmy.fx.control.caspian.CaspianDriverFactory; 35 import org.jemmy.interfaces.Keyboard.KeyboardButton; 36 import org.jemmy.interfaces.Keyboard.KeyboardButtons; 37 import org.jemmy.interfaces.Keyboard.KeyboardModifiers; 38 import org.jemmy.interfaces.Parent; 39 import org.jemmy.interfaces.Selectable; 40 import org.jemmy.lookup.Lookup; 41 import org.jemmy.lookup.LookupCriteria; 42 import org.jemmy.timing.State; 43 import static org.junit.Assert.*; 44 import org.junit.*; 45 import org.junit.runner.RunWith; 46 import test.javaclient.shared.FilteredTestRunner; 47 import test.javaclient.shared.JemmyUtils; 48 import test.javaclient.shared.Utils; 49 import test.javaclient.shared.screenshots.ImagesManager; 50 import test.javaclient.shared.screenshots.ScreenshotUtils; 51 52 @RunWith(FilteredTestRunner.class) 53 public class RichTextEditorTest extends ControlsTestBase { 54 55 public RichTextEditorTest() { 56 } 57 static Wrap<? extends Scene> scene = null; 58 static Parent<Node> parent = null; 59 static Wrap resetBtn; 60 static Wrap contentPane = null; 61 Wrap<? extends WebView> webView = null; 62 Wrap cut = null; 63 Wrap copy = null; 64 Wrap paste = null; 65 Wrap undo = null; 66 Wrap redo = null; 67 Wrap separator = null; 68 Wrap left = null; 69 Wrap center = null; 70 Wrap right = null; 71 Wrap adjust = null; 72 Wrap bullets = null; 73 Wrap numbers = null; 74 Wrap indent = null; 75 Wrap removeIndent = null; 76 Wrap<? extends ComboBox> paragraph = null; 77 Wrap<? extends ComboBox> fontStyle = null; 78 Wrap<? extends ComboBox> fontSize = null; 79 Wrap<? extends ToggleButton> bold = null; 80 Wrap<? extends ToggleButton> italic = null; 81 Wrap<? extends ToggleButton> underline = null; 82 Wrap<? extends ToggleButton> crossed = null; 83 Wrap foreground = null; 84 Wrap background = null; 85 Wrap<? extends HTMLEditor> htmlEditor = null; 86 Parent htmlEditorAsParent; 87 protected static KeyboardModifiers CTRL_DOWN_MASK_OS; 88 public static String DEFAULT_TEXT_STYLE = "ArialW7"; 89 public static String PLATFORM_TAG; 90 91 static { 92 if (Utils.isMacOS()) { 93 CTRL_DOWN_MASK_OS = KeyboardModifiers.META_DOWN_MASK; 94 PLATFORM_TAG = "mac_"; 95 } else { 96 CTRL_DOWN_MASK_OS = KeyboardModifiers.CTRL_DOWN_MASK; 97 if (Utils.isWindows8()) { 98 PLATFORM_TAG = "win8_"; 99 } else if (Utils.isWindows()) { 100 PLATFORM_TAG = "win_"; 101 } else { 102 PLATFORM_TAG = "lin_"; 103 } 104 } 105 } 106 107 @BeforeClass 108 public static void setUpClass() throws Exception { 109 RichTextEditorApp.main(null); 110 scene = Root.ROOT.lookup().wrap(); 111 parent = scene.as(Parent.class, Node.class); 112 resetBtn = parent.lookup(new ByID(RichTextEditorApp.RESET_BUTTON_ID)).wrap(); 113 contentPane = parent.lookup(new ByID<Node>(RichTextEditorApp.TEST_PANE_ID)).wrap(); 114 } 115 116 @AfterClass 117 public static void tearDownClass() throws Exception { 118 } 119 120 @Before 121 public void setUp() { 122 JemmyUtils.comparatorDistance = 0.01f; 123 reset(); 124 if (!Utils.isLinux() && !Utils.isMacOS()) //Temporary. Need to be explored, why it generates exception on linux. 125 { 126 Toolkit.getDefaultToolkit().setLockingKeyState(java.awt.event.KeyEvent.VK_NUM_LOCK, false); 127 } 128 } 129 130 @After 131 public void tearDown() { 132 } 133 134 // @ScreenshotCheck 135 // @Test(timeout=300000) //platform specific 136 // public void fontStylesTest() throws InterruptedException, IOException, Throwable { 137 // final Parent<RadioMenuItem> attributes = fontStyle.as(Parent.class, RadioMenuItem.class); 138 // for (int i = 0; i < attributes.lookup().size(); i++) { 139 // Wrap<? extends RadioMenuItem> attribute = attributes.lookup().wrap(i); 140 // attribute.mouse().click(); 141 // typeText(getAttributeText("paragraph", attribute.getControl().getText()) + "\n"); 142 // } 143 // check(""); 144 // } 145 @ScreenshotCheck 146 @Test(timeout = 300000) 147 @Keywords(keywords="webkit") 148 public void textSelectionTest() throws InterruptedException, IOException, Throwable { 149 int someRandomColor = 19; 150 typeText(SOME_TEXT); 151 webView.keyboard().pushKey(KeyboardButtons.ENTER); 152 typeText(SOME_OTHER_TEXT); 153 for (int i = 0; i < SOME_OTHER_TEXT.length() + 1; i++) { 154 webView.keyboard().pushKey(KeyboardButtons.LEFT); 155 } 156 webView.keyboard().pressKey(KeyboardButtons.SHIFT); 157 try { 158 for (int i = 0; i < SOME_OTHER_TEXT.length() + 1; i++) { 159 webView.keyboard().pushKey(KeyboardButtons.LEFT); 160 } 161 } finally { 162 webView.keyboard().releaseKey(KeyboardButtons.SHIFT); 163 } 164 color(background, "background", someRandomColor); 165 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 166 webView.keyboard().pushKey(KeyboardButtons.RIGHT); 167 ScreenshotUtils.checkScreenshot("RichTextEditor-textSelection", webView); 168 throwScreenshotError(); 169 } 170 171 @ScreenshotCheck 172 @Test(timeout = 300000) 173 @Keywords(keywords="webkit") 174 public void textStyleReflectionTest() throws InterruptedException, IOException, Throwable { 175 typeText(HELLO_WORLD); 176 webView.keyboard().pushKey(KeyboardButtons.ENTER); 177 setParagraph(HEADING1); 178 typeText(SOME_TEXT); 179 ScreenshotUtils.checkScreenshot("RichTextEditor-textStyleReflection1", contentPane); 180 webView.keyboard().pushKey(KeyboardButtons.ENTER); 181 setParagraph(HEADING2); 182 typeText(SOME_OTHER_TEXT); 183 ScreenshotUtils.checkScreenshot("RichTextEditor-textStyleReflection2", contentPane); 184 throwScreenshotError(); 185 } 186 187 @ScreenshotCheck 188 @Test(timeout = 300000) 189 @Keywords(keywords="webkit") 190 public void headingIssueTest() throws InterruptedException, IOException, Throwable { 191 setParagraph(HEADING1); 192 typeText(SOME_TEXT); 193 webView.keyboard().pushKey(KeyboardButtons.ENTER); 194 setParagraph(HEADING2); 195 typeText(SOME_OTHER_TEXT); 196 for (int i = 0; i < SOME_OTHER_TEXT.length(); i++) { 197 webView.keyboard().pushKey(KeyboardButtons.LEFT); 198 } 199 webView.keyboard().pushKey(KeyboardButtons.BACK_SPACE); 200 ScreenshotUtils.checkScreenshot("RichTextEditor-headingIssue", webView); 201 check("heading_issue"); 202 throwScreenshotError(); 203 } 204 205 @Smoke 206 @Test(timeout = 300000) 207 @Keywords(keywords="webkit") 208 public void setHtmlTest() throws InterruptedException, IOException { 209 SimpleStringProperty ssp = new SimpleStringProperty(); 210 ssp.set(LIST); 211 setHTML(HTML_SAMPLE_TEXT); 212 String res = getHTML(); 213 assertEquals(HTML_SAMPLE_TEXT, res); 214 } 215 216 @ScreenshotCheck 217 @Test(timeout = 300000) 218 @Keywords(keywords="webkit") 219 public void checkStylesTest() throws Throwable { 220 setParagraph(HEADING1); 221 typeText(SOME_TEXT); 222 setFontSize(XX_LARGE_FONT_SIZE); 223 typeText(SOME_OTHER_TEXT); 224 setParagraph(HEADING6); 225 ScreenshotUtils.checkScreenshot("RichTextEditor-styles", webView); 226 throwScreenshotError(); 227 } 228 229 @ScreenshotCheck 230 @Smoke 231 @Test(timeout = 300000) 232 @Keywords(keywords="webkit") 233 public void initialStateTest() throws InterruptedException { 234 ScreenshotUtils.checkScreenshot("RichTextEditor-initialState", contentPane); 235 } 236 237 @Smoke 238 @Test(timeout = 300000) 239 @Keywords(keywords="webkit") 240 public void deletingEmptyStringTest() throws InterruptedException, IOException, Throwable { 241 webView.keyboard().pushKey(KeyboardButtons.ENTER); 242 webView.keyboard().pushKey(KeyboardButtons.ENTER); 243 webView.keyboard().pushKey(KeyboardButtons.UP); 244 webView.keyboard().pushKey(KeyboardButtons.UP); 245 webView.keyboard().pushKey(KeyboardButtons.DELETE); 246 webView.keyboard().pushKey(KeyboardButtons.DOWN); 247 webView.keyboard().pushKey(KeyboardButtons.DOWN); 248 webView.keyboard().pushKey(KeyboardButtons.BACK_SPACE); 249 assertTrue(getHTML().equals(readResource("deleting_empty_string_test.html"))); 250 } 251 252 @ScreenshotCheck 253 @Test(timeout = 300000) //rt-20500 -- html when possible 254 @Keywords(keywords="webkit") 255 public void unexpectedlyTextSelectionTest() throws InterruptedException, IOException, Throwable { 256 final String hw = "Hello, World!"; 257 typeText(hw); 258 for (int i = 0; i < hw.length(); i++) { 259 webView.keyboard().pushKey(KeyboardButtons.LEFT); 260 } 261 webView.keyboard().pushKey(KeyboardButtons.Q); 262 webView.keyboard().pushKey(KeyboardButtons.W); 263 webView.keyboard().pushKey(KeyboardButtons.E); 264 webView.keyboard().pushKey(KeyboardButtons.R); 265 webView.keyboard().pushKey(KeyboardButtons.T); 266 webView.keyboard().pushKey(KeyboardButtons.Y); 267 checkScreenshot("RichTextEditor-unexpectedly-text-selection", webView); 268 throwScreenshotError(); 269 } 270 271 @ScreenshotCheck 272 @Test(timeout = 300000) 273 @Keywords(keywords="webkit") 274 public void separatorTest() throws InterruptedException, IOException { 275 webView.mouse().click(); 276 separator.mouse().click(); 277 check("separator"); 278 ScreenshotUtils.checkScreenshot("RichTextEditor-separator", webView); 279 } 280 281 @ScreenshotCheck 282 @Test(timeout = 300000) 283 @Keywords(keywords="webkit") 284 public void alignmentTest() throws InterruptedException, IOException, Throwable { 285 typeText(ALIGNMENT_TEXT); 286 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 287 alignment(left, "left"); 288 alignment(right, "right"); 289 alignment(center, "center"); 290 alignment(adjust, "adjust"); 291 292 kbdClear(); 293 294 Map<Wrap<? extends ToggleButton>, String> map = new LinkedHashMap<Wrap<? extends ToggleButton>, String>(); 295 map.put(left, "left"); 296 map.put(right, "right"); 297 map.put(center, "center"); 298 map.put(adjust, "adjust"); 299 300 for (int j = 0; j < map.size(); j++) { 301 Entry<Wrap<? extends ToggleButton>, String> param = (Entry<Wrap<? extends ToggleButton>, String>) map.entrySet().toArray()[j]; 302 param.getKey().as(Selectable.class, Boolean.class).selector().select(true); 303 typeText(param.getValue() + "\n"); 304 } 305 306 moveToTextBegin(); 307 308 for (int j = 0; j < map.size(); j++) { 309 Entry<Wrap<? extends ToggleButton>, String> param = (Entry<Wrap<? extends ToggleButton>, String>) map.entrySet().toArray()[j]; 310 param.getKey().waitProperty(TextControlWrap.SELECTED_PROP_NAME, true); 311 webView.keyboard().pushKey(KeyboardButtons.END); 312 param.getKey().waitProperty(TextControlWrap.SELECTED_PROP_NAME, true); 313 pushKey(KeyboardButtons.DOWN, 1); 314 } 315 316 throwScreenshotError(); 317 } 318 319 @ScreenshotCheck 320 @Test(timeout = 300000) 321 @Keywords(keywords = "webkit") 322 public void fontSizeTest() throws InterruptedException, IOException, Throwable { 323 //We need to change step of scrolling, because list view behavior doesn't allow to select the last item. 324 final int val = Math.round(((CaspianDriverFactory) ThemeDriverFactory.getThemeFactory()).getDragDelta()); 325 ((CaspianDriverFactory) ThemeDriverFactory.getThemeFactory()).setDragDelta(20); 326 attributes(fontSize, "size"); 327 ((CaspianDriverFactory) ThemeDriverFactory.getThemeFactory()).setDragDelta(val); 328 reset(); 329 } 330 331 @ScreenshotCheck 332 @Test(timeout = 300000) 333 @Keywords(keywords="webkit") 334 public void fontStyleTest() throws InterruptedException, IOException, Throwable { 335 attributes(fontStyle, "style", 4); 336 } 337 338 @ScreenshotCheck 339 @Test(timeout = 300000) //rt -- 20500 update when possible 340 @Keywords(keywords="webkit") 341 public void paragraphTest() throws InterruptedException, IOException, Throwable { 342 final Parent<RadioMenuItem> attributes = paragraph.as(Parent.class, RadioMenuItem.class); 343 for (int i = 0; i < attributes.lookup().size(); i++) { 344 Wrap<? extends RadioMenuItem> attribute = attributes.lookup().wrap(i); 345 attribute.mouse().click(); 346 typeText(getAttributeText("paragraph", attribute.getControl().getText()) + "\n"); 347 } 348 349 moveToTextBegin(); 350 351 paragraph.waitProperty(Wrap.TEXT_PROP_NAME, attributes.lookup().wrap(0).getControl().getText()); 352 for (int i = 0; i < attributes.lookup().size(); i++) { 353 Wrap<? extends RadioMenuItem> attribute = attributes.lookup().wrap(i); 354 paragraph.waitProperty(Wrap.TEXT_PROP_NAME, attribute.getControl().getText()); 355 pushKey(KeyboardButtons.DOWN, 1); 356 } 357 358 check("paragraph"); 359 360 checkScreenshot("RichTextEditor-font-paragraph", webView); 361 362 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 363 checkScreenshot("RichTextEditor-font-paragraph-selected", webView); 364 365 throwScreenshotError(); 366 } 367 368 @ScreenshotCheck 369 @Test(timeout = 300000) 370 public void typefaceTest() throws InterruptedException, IOException, Throwable { 371 Map<Wrap<? extends ToggleButton>, String> map = new LinkedHashMap<Wrap<? extends ToggleButton>, String>(); 372 map.put(bold, "bold"); 373 map.put(italic, "italic"); 374 map.put(underline, "underline"); 375 map.put(crossed, "crossed"); 376 377 for (Integer i = 0; i < (1 << map.size()); i++) { 378 String text = new String(); 379 for (int j = 0; j < map.size(); j++) { 380 Entry<Wrap<? extends ToggleButton>, String> param = (Entry<Wrap<? extends ToggleButton>, String>) map.entrySet().toArray()[j]; 381 Boolean selected = ((i >> j) & 1) > 0; 382 param.getKey().as(Selectable.class, Boolean.class).selector().select(selected); 383 text += (selected ? "" : "not ") + param.getValue() + " "; 384 } 385 typeText(text); 386 } 387 388 moveToTextBegin(); 389 390 for (int j = 0; j < map.size(); j++) { 391 Wrap<? extends ToggleButton> wrap = (Wrap<? extends ToggleButton>) map.keySet().toArray()[j]; 392 wrap.waitProperty(TextControlWrap.SELECTED_PROP_NAME, false); 393 } 394 pushKey(KeyboardButtons.RIGHT, 1); 395 for (Integer i = 0; i < (1 << map.size()); i++) { 396 String text = new String(); 397 for (int j = 0; j < map.size(); j++) { 398 Entry<Wrap<? extends ToggleButton>, String> param = (Entry<Wrap<? extends ToggleButton>, String>) map.entrySet().toArray()[j]; 399 Boolean selected = ((i >> j) & 1) > 0; 400 param.getKey().waitProperty(TextControlWrap.SELECTED_PROP_NAME, selected); 401 text += (selected ? "" : "not ") + param.getValue() + " "; 402 } 403 pushKey(KeyboardButtons.RIGHT, text.length()); 404 } 405 406 checkScreenshot("RichTextEditor-typeface", webView); 407 408 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 409 checkScreenshot("RichTextEditor-typeface-selected", webView); 410 411 throwScreenshotError(); 412 } 413 414 @ScreenshotCheck 415 @Test(timeout = 300000) 416 @Keywords(keywords="webkit") 417 public void colorTest() throws InterruptedException, IOException, Throwable { 418 for (int i = 0; i < 3; i++) { 419 String fore = color(foreground, "foreground", i); 420 for (int j = 3; j < 6; j++) { 421 String back = color(background, "background", j); 422 typeText("[" + fore + "; " + back + "] "); 423 } 424 } 425 check("color"); 426 427 checkScreenshot("RichTextEditor-colors", webView); 428 429 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 430 checkScreenshot("RichTextEditor-colors-selected", webView); 431 432 throwScreenshotError(); 433 } 434 435 @ScreenshotCheck 436 @Test(timeout = 300000) 437 @Keywords(keywords="webkit") 438 public void resetTest() throws InterruptedException, IOException, Throwable { 439 for (int i = 0; i < 30; ++i) { 440 reset(); 441 } 442 checkScreenshot("RichTextEditor-reset", scene); 443 throwScreenshotError(); 444 } 445 446 @ScreenshotCheck 447 @Test(timeout = 300000) 448 @Keywords(keywords="webkit") 449 public void countTest() throws InterruptedException, IOException, Throwable { 450 countSequential(numbers, "number"); 451 Thread.sleep(500); 452 countSequential(bullets, "bullet"); 453 check("count"); 454 checkScreenshot("RichTextEditor-count-sequential", webView); 455 kbdClear(); 456 check("empty-count"); 457 checkScreenshot("RichTextEditor-count-clear", webView); 458 throwScreenshotError(); 459 } 460 461 @ScreenshotCheck 462 @Test(timeout = 300000) 463 @Keywords(keywords="webkit") 464 public void countChangeTypeTest() throws InterruptedException, IOException, Throwable { 465 countSequential(numbers, "number"); 466 check("count_numbers"); 467 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 468 bullets.mouse().click(); 469 check("count_bullets"); 470 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 471 numbers.mouse().click(); 472 check("count_numbers2"); 473 checkScreenshot("RichTextEditor-count-change-type", webView); 474 throwScreenshotError(); 475 } 476 477 @ScreenshotCheck 478 @Test(timeout = 300000) 479 @Keywords(keywords="webkit") 480 public void countRemoveIndentTest() throws InterruptedException, IOException, Throwable { 481 countSimple(numbers, "number"); 482 moveToTextBegin(); 483 removeIndent.mouse().click(); 484 check("count_numbers_remove_indent"); 485 checkScreenshot("RichTextEditor-indent-remove", webView); 486 throwScreenshotError(); 487 } 488 489 @ScreenshotCheck 490 @Test(timeout = 300000) 491 @Keywords(keywords="webkit") 492 public void countIndentTest() throws InterruptedException, IOException, Throwable { 493 countSimple(numbers, "number"); 494 check("simple_numbers"); 495 moveToTextBegin(); 496 for (int i = 0; i < SHORT_LIST_LENTGTH; i++) { 497 indent.mouse().click(); 498 check("count_numbers_indent_" + i + ""); 499 checkScreenshot("RichTextEditor-indent-" + i, webView); 500 removeIndent.mouse().click(); 501 //check("simple_numbers"); 502 webView.keyboard().pushKey(KeyboardButtons.DOWN); 503 } 504 throwScreenshotError(); 505 } 506 507 @ScreenshotCheck 508 @Test(timeout = 300000) //platform specific OK except bug 20500 509 @Keywords(keywords="webkit") 510 public void compositeTest() throws InterruptedException, IOException, Throwable { 511 HashMap<Wrap, Integer> map = getAttributesMap(); 512 typeText(LINE); 513 514 final int SHIFT = 4; 515 final int RANGE = SHIFT * (map.size() + 1); 516 assertTrue(2 * map.size() * SHIFT < LINE.length()); 517 for (int i = 0; i < map.size(); i++) { 518 int start = i * SHIFT; 519 selectRange(start, start + RANGE); 520 Entry<Wrap, Integer> param = (Entry<Wrap, Integer>) map.entrySet().toArray()[i]; 521 int index = param.getValue(); 522 Wrap wrap = param.getKey(); 523 if (index == -1) { 524 wrap.mouse().click(); 525 } else { 526 if (ColorPicker.class.isAssignableFrom(wrap.getControl().getClass())) { 527 color(wrap, "", index); 528 } else { 529 selectAttribute(wrap, index); 530 } 531 } 532 } 533 selectRange(0, 0); 534 check("composite"); 535 checkScreenshot("RichTextEditor-composite", webView); 536 throwScreenshotError(); 537 } 538 539 @Smoke 540 @Test(timeout = 300000) //http://javafx-jira.kenai.com/browse/RT-20554 541 @Keywords(keywords="webkit") 542 public void copyTest() throws InterruptedException, IOException, Throwable { 543 clipboard(copy, "copy"); 544 } 545 546 @Smoke 547 @Test(timeout = 300000) //http://javafx-jira.kenai.com/browse/RT-20554 548 @Keywords(keywords="webkit") 549 public void cutTest() throws InterruptedException, IOException, Throwable { 550 clipboard(cut, "cut"); 551 } 552 553 @Smoke 554 @Test(timeout = 300000) //http://javafx-jira.kenai.com/browse/RT-20554 555 @Keywords(keywords="webkit") 556 public void pasteTest() throws InterruptedException, IOException, Throwable { 557 typeText(ALIGNMENT_TEXT); 558 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 559 copy.mouse().click(); 560 webView.keyboard().pushKey(KeyboardButtons.DELETE); 561 paste.mouse().click(); 562 System.out.println(getHTML()); 563 check("paste"); 564 } 565 566 // @ScreenshotCheck 567 // @Test(timeout=300000) 568 // public void undoRedoTest() throws InterruptedException, IOException, Throwable { 569 // typeText(SHORT_LIST); 570 // String html = htmlEditor.getControl().getHtmlText(); 571 // undo.mouse().click(); 572 // check("empty"); 573 // redo.mouse().click(); 574 // htmlEditor.waitState(new State<String>() { 575 // public String reached() { 576 // return htmlEditor.getControl().getHtmlText(); 577 // } 578 // }, html); 579 // } 580 protected void setParagraph(int num) throws InterruptedException { 581 paragraph.mouse().click(); 582 final Parent<Node> attributes = (Parent<Node>) getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap(0).as(Parent.class, Node.class); 583 if (num < 0 || num > attributes.lookup(ListCell.class).size()) { 584 num = 0; 585 } 586 attributes.lookup(ListCell.class).wrap(num).mouse().click(); 587 setDefaultFont(); 588 } 589 590 protected void setFontSize(int num) throws InterruptedException { 591 fontSize.mouse().click(); 592 final Parent<Node> attributes = (Parent<Node>) getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap(0).as(Parent.class, Node.class); 593 if (num < 0 || num > attributes.lookup(ListCell.class).size()) { 594 num = 0; 595 } 596 attributes.lookup(ListCell.class).wrap(num).mouse().click(); 597 } 598 599 protected void setFont(int num) throws InterruptedException { 600 fontStyle.mouse().click(); 601 final Parent<Node> attributes = (Parent<Node>) getPopupWrap().as(Parent.class, Node.class).lookup(ListView.class).wrap(0).as(Parent.class, Node.class); 602 if (num < 0 || num > attributes.lookup(ListCell.class).size()) { 603 num = 0; 604 } 605 attributes.lookup(ListCell.class).wrap(num).mouse().click(); 606 } 607 608 protected HashMap<Wrap, Integer> getAttributesMap() { 609 HashMap<Wrap, Integer> map = new LinkedHashMap<Wrap, Integer>(); 610 map.put(fontSize, 4); 611 map.put(fontStyle, 3); 612 //map.put(paragraph, 2); 613 map.put(bold, -1); 614 map.put(italic, -1); 615 map.put(underline, -1); 616 map.put(crossed, -1); 617 map.put(foreground, 3); 618 map.put(background, 4); 619 return map; 620 } 621 622 protected void clipboard(final Wrap<? extends Node> wrap, String html) throws IOException { 623 typeText(ALIGNMENT_TEXT); 624 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 625 wrap.waitState(new State<Boolean>() { 626 627 public Boolean reached() { 628 return new GetAction<Boolean>() { 629 630 @Override 631 public void run(Object... parameters) { 632 setResult(wrap.getControl().isDisabled()); 633 } 634 }.dispatch(Root.ROOT.getEnvironment()); 635 } 636 }, false); 637 wrap.mouse().click(); 638 checkClipboard(html); 639 } 640 641 protected void selectAttribute(Wrap<? extends MenuButton> wrap, int index) { 642 final Parent<RadioMenuItem> attributes = wrap.as(Parent.class, RadioMenuItem.class); 643 Wrap<? extends RadioMenuItem> attribute = attributes.lookup().wrap(index); 644 attribute.mouse().click(); 645 } 646 647 protected void selectRange(int min, int max) { 648 setPos(min); 649 setPos(max, KeyboardModifiers.SHIFT_DOWN_MASK); 650 } 651 int current_pos = -1; 652 653 protected void setPos(int pos, KeyboardModifiers... mdfs) { 654 if (current_pos == -1 || mdfs.length == 0) { 655 moveToTextBegin(); 656 current_pos = 0; 657 } 658 if (current_pos < pos) { 659 pushKey(KeyboardButtons.RIGHT, pos - current_pos, mdfs); 660 } else { 661 pushKey(KeyboardButtons.LEFT, current_pos - pos, mdfs); 662 } 663 current_pos = pos; 664 } 665 666 public void countSequential(Wrap wrap, String name) throws InterruptedException, IOException, Throwable { 667 wrap.mouse().click(); 668 typeText(SHORT_LIST); 669 typeText("\n"); 670 wrap.mouse().click(); 671 typeText(SHORT_LIST); 672 typeText("\n\n"); 673 wrap.mouse().click(); 674 typeText(SHORT_LIST); 675 } 676 677 public void countSimple(Wrap wrap, String name) throws InterruptedException, IOException, Throwable { 678 wrap.mouse().click(); 679 setDefaultFont(); 680 typeText(SHORT_LIST); 681 typeText("\n"); 682 } 683 684 /** 685 * Selects color from dropdown. 686 * @param control - part of color picker visible on a panel. 687 * @param name - just a name 688 * @param num - index of the color 689 * @return 690 * @throws InterruptedException 691 * @throws IOException 692 * @throws Throwable 693 */ 694 protected String color(Wrap control, String name, int num) throws InterruptedException, IOException, Throwable { 695 control.mouse().click(); 696 Wrap<? extends Scene> drop_scene = Root.ROOT.lookup(new LookupCriteria<Scene>() { 697 698 public boolean check(Scene sc) { 699 return sc != scene.getControl() && sc.getWindow().isShowing(); 700 } 701 }).wrap(); 702 Parent<Node> drop_scene_parent = drop_scene.as(Parent.class, Node.class); 703 Lookup<Node> color_lookup = drop_scene_parent.lookup(new LookupCriteria<Node>() { 704 705 public boolean check(Node cntrl) { 706 return cntrl.getStyleClass().contains("color-square") || cntrl.getStyleClass().contains("color-square-selected"); 707 } 708 }); 709 710 Wrap wrap = color_lookup.wrap(num); 711 double[] colors = getColors(wrap.getScreenImage()); 712 wrap.mouse().click(); 713 return name + ": (" + colors[0] + ", " + colors[1] + ", " + colors[2] + ")"; 714 } 715 716 public void attributes(Wrap<? extends ComboBox> wrap, String name, int... counter) throws InterruptedException, IOException, Throwable { 717 int c = 0; 718 for (int i = 0; i < wrap.as(Selectable.class).getStates().size(); i++) { 719 if (counter.length > 0) { 720 if (c++ >= counter[0]) { 721 break; 722 } 723 } 724 wrap.as(Selectable.class).selector().select(wrap.as(Selectable.class).getStates().get(i)); 725 typeText(getAttributeText(name, wrap.as(Selectable.class).getStates().get(i).toString())); 726 } 727 728 moveToTextBegin(); 729 checkComboBoxValue(wrap, wrap.as(Selectable.class).getStates().get(0).toString()); 730 pushKey(KeyboardButtons.RIGHT, 1); 731 c = 0; 732 for (int i = 0; i < wrap.as(Selectable.class).getStates().size(); i++) { 733 if (counter.length > 0) { 734 if (c++ >= counter[0]) { 735 break; 736 } 737 } 738 checkComboBoxValue(wrap, wrap.as(Selectable.class).getStates().get(i).toString()); 739 pushKey(KeyboardButtons.RIGHT, getAttributeText(name, wrap.as(Selectable.class).getStates().get(i).toString()).length()); 740 } 741 742 check(name); 743 744 checkScreenshot("RichTextEditor-font-" + name, webView); 745 746 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 747 checkScreenshot("RichTextEditor-font-" + name + "-selected", webView); 748 749 throwScreenshotError(); 750 } 751 752 protected void checkComboBoxValue(final Wrap<? extends ComboBox> wrap, String expectedValue) { 753 wrap.waitState(new State<String>() { 754 public String reached() { 755 return new GetAction<String>() { 756 @Override 757 public void run(Object... os) throws Exception { 758 setResult(wrap.getControl().getValue().toString()); 759 } 760 }.dispatch(Root.ROOT.getEnvironment()); 761 } 762 }, expectedValue); 763 } 764 765 protected void alignment(Wrap wrap, String name) throws InterruptedException, IOException, Throwable { 766 wrap.mouse().click(); 767 check(name + "_alignment"); 768 checkScreenshot("RichTextEditor-alignment-" + name, webView); 769 } 770 771 private List<MenuItem> getFonts() { 772 return new GetAction<List<MenuItem>>() { 773 774 @Override 775 public void run(Object... os) throws Exception { 776 ArrayList res = new ArrayList(); 777 int size = fontStyle.as(Parent.class, MenuItem.class).lookup().size(); 778 for (int i = 0; i < size; i++) { 779 res.add(fontStyle.as(Parent.class, MenuItem.class).lookup().get(i)); 780 } 781 setResult(res); 782 783 //setResult(((MenuButton)fontStyle.getControl()).getItems().listIterator()); 784 } 785 }.dispatch(htmlEditor.getEnvironment()); 786 } 787 788 protected void setFont(String name) { 789 fontStyle.as(Selectable.class).selector().select(name); 790 // ListIterator<MenuItem> li = getFonts().listIterator(); 791 // MenuItem mi; 792 // int i = 0; 793 // do { 794 // mi = li.next(); 795 // i++; 796 // } while (!mi.getText().equals(name)); 797 // setFont(--i); 798 } 799 800 private void setDefaultFont() { 801 setFont(DEFAULT_TEXT_STYLE); 802 } 803 804 void reset() { 805 resetBtn.mouse().click(); 806 807 webView = parent.lookup(WebView.class).wrap(); 808 webView.mouse().click(); 809 810 htmlEditor = parent.lookup(HTMLEditor.class).wrap(); 811 htmlEditorAsParent = htmlEditor.as(Parent.class, Node.class); 812 813 cut = parent.lookup(Button.class).wrap(0); 814 copy = parent.lookup(Button.class).wrap(1); 815 paste = parent.lookup(Button.class).wrap(2); 816 // undo = parent.lookup(Button.class).wrap(3); 817 // redo = parent.lookup(Button.class).wrap(4); 818 left = parent.lookup(ToggleButton.class).wrap(0); 819 center = parent.lookup(ToggleButton.class).wrap(1); 820 right = parent.lookup(ToggleButton.class).wrap(2); 821 adjust = parent.lookup(ToggleButton.class).wrap(3); 822 bullets = parent.lookup(ToggleButton.class).wrap(4); 823 numbers = parent.lookup(ToggleButton.class).wrap(5); 824 indent = parent.lookup(Button.class).wrap(3); 825 removeIndent = parent.lookup(Button.class).wrap(4); 826 separator = parent.lookup(Button.class).wrap(5); 827 828 paragraph = parent.lookup(ComboBox.class).wrap(0); 829 fontStyle = parent.lookup(ComboBox.class).wrap(1); 830 fontSize = parent.lookup(ComboBox.class).wrap(2); 831 832 bold = parent.lookup(ToggleButton.class).wrap(6); 833 italic = parent.lookup(ToggleButton.class).wrap(7); 834 underline = parent.lookup(ToggleButton.class).wrap(8); 835 crossed = parent.lookup(ToggleButton.class).wrap(9); 836 837 foreground = parent.lookup(ColorPicker.class).wrap(0); 838 background = parent.lookup(ColorPicker.class).wrap(1); 839 setDefaultFont(); 840 } 841 842 private String getHTMLName(String name) { 843 String plsSpecName = PLATFORM_TAG + name; 844 File plSpec; 845 URL url = getClass().getResource(plsSpecName + ".html"); 846 if (url != null) { 847 plSpec = new File(url.getFile()); 848 if (plSpec != null && plSpec.exists()) { 849 return plsSpecName; 850 } 851 } 852 //If no win8, use other win. 853 if (PLATFORM_TAG.contains("win8_") && url == null) { 854 plsSpecName = "win_" + name; 855 url = getClass().getResource(plsSpecName + ".html"); 856 if (url != null) { 857 plSpec = new File(url.getFile()); 858 if (plSpec != null && plSpec.exists()) { 859 return plsSpecName; 860 } 861 } 862 } 863 864 System.out.println("there is no platform specific html for name <" + name + ">."); 865 return name; 866 } 867 868 protected void check(final String html) throws IOException, FileNotFoundException { 869 System.out.println(readResource(getHTMLName(html) + ".html")); 870 try { 871 htmlEditor.waitState(new State<String>() { 872 873 public String reached() { 874 System.out.println(htmlEditor.getControl().getHtmlText()); 875 return htmlEditor.getControl().getHtmlText(); 876 } 877 }, readResource(getHTMLName(html) + ".html")); 878 } finally { 879 Writer out = new OutputStreamWriter(new FileOutputStream(ImagesManager.getInstance().getHTMLPath(html))); 880 try { 881 out.write("Found : " + htmlEditor.getControl().getHtmlText() + "\n"); 882 out.write("Expected : " + readResource(getHTMLName(html) + ".html") + "\n"); 883 } finally { 884 out.close(); 885 } 886 } 887 } 888 889 protected void checkClipboard(String html) throws IOException { 890 try { 891 htmlEditor.waitState(new State<String>() { 892 893 public String reached() { 894 return getClipboardHTML(); 895 } 896 }, readResource(getHTMLName(html) + ".html")); 897 } finally { 898 Writer out = new OutputStreamWriter(new FileOutputStream(ImagesManager.getInstance().getHTMLPath(html))); 899 try { 900 out.write(getClipboardHTML()); 901 } finally { 902 out.close(); 903 } 904 } 905 } 906 907 protected void typeText(String text) { 908 for (int i = 0; i < text.length(); i++) { 909 char c = text.charAt(i); 910 if (c == '\n') { 911 webView.keyboard().pushKey(KeyboardButtons.ENTER); 912 } else { 913 webView.keyboard().typeChar(text.charAt(i), ZERO_TIMEOUT); 914 } 915 } 916 } 917 918 protected String readResource(String name) throws IOException { 919 URL url = RichTextEditorTest.class.getResource(name); 920 assertNotNull(url); 921 BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); 922 StringBuilder result = new StringBuilder(); 923 while (true) { 924 int c = reader.read(); 925 if (c == -1) { 926 break; 927 } 928 result.append((char) c); 929 } 930 return result.toString(); 931 } 932 933 protected String getClipboardHTML() { 934 return new GetAction<String>() { 935 936 @Override 937 public void run(Object... os) throws Exception { 938 setResult(Clipboard.getSystemClipboard().getHtml()); 939 } 940 }.dispatch(htmlEditor.getEnvironment()); 941 } 942 943 protected String getHTML() { 944 return new GetAction<String>() { 945 946 @Override 947 public void run(Object... parameters) { 948 setResult(htmlEditor.getControl().getHtmlText()); 949 } 950 }.dispatch(Root.ROOT.getEnvironment()); 951 } 952 953 protected void setHTML(final String html) { 954 new GetAction() { 955 956 @Override 957 public void run(Object... parameters) { 958 htmlEditor.getControl().setHtmlText(html); 959 } 960 }.dispatch(Root.ROOT.getEnvironment()); 961 } 962 963 protected String getAttributeText(String attribute, String value) { 964 return attribute + " " + value + " "; 965 } 966 967 protected void pushKey(KeyboardButton kb, int count, KeyboardModifiers... mods) { 968 for (int k = 0; k < count; k++) { 969 webView.keyboard().pushKey(ZERO_TIMEOUT, kb, mods); 970 } 971 } 972 973 protected void kbdClear() { 974 webView.keyboard().pushKey(KeyboardButtons.A, CTRL_DOWN_MASK_OS); 975 webView.keyboard().pushKey(KeyboardButtons.DELETE); 976 } 977 978 protected void moveToTextBegin() { 979 if (Utils.isMacOS()) { 980 webView.keyboard().pushKey(KeyboardButtons.UP, KeyboardModifiers.META_DOWN_MASK); 981 } else { 982 webView.keyboard().pushKey(KeyboardButtons.HOME, KeyboardModifiers.CTRL_DOWN_MASK); 983 } 984 } 985 986 private Wrap<? extends Scene> getPopupWrap() throws InterruptedException { 987 Wrap<? extends Scene> temp; 988 try { 989 temp = Root.ROOT.lookup(new ByWindowType(PopupWindow.class)).lookup(Scene.class).wrap(0); 990 } catch (Exception e) { 991 return null; 992 } 993 return temp; 994 } 995 final static String SOME_TEXT = "some text"; 996 final static String HELLO_WORLD = "Hello, World!"; 997 final static String SOME_OTHER_TEXT = "some more text"; 998 final static String HTML_SAMPLE_TEXT = "<html><head></head><body contenteditable=\"true\"><div style=\"text-align: left;\"><div style=\"text-align: left;\">\"<b>Sing, O goddess, the anger of<i> </i></b><i>Achilles <u>son </u></i><u>of Pele<strike>us, that brou</strike></u>ght </div><hr><h5>c<font class=\"Apple-style-span\" face=\"CordiaUPC\">ountless ills up</font>o<font class=\"Apple-style-span\" size=\"4\">n the Achaeans. Many<font class=\"Apple-style-span\" face=\"'Comic Sans MS'\"> </font></font><font class=\"Apple-style-span\" face=\"'Comic Sans MS'\">a brave sou</font><font class=\"Apple-style-span\" face=\"David\">l <font class=\"Apple-style-span\" size=\"4\">di</font></font><font class=\"Apple-style-span\" face=\"David\" style=\"font-size: large; \">d it send hurrying down to Hades, and many a hero did it yield a prey to dogs and </font><font class=\"Apple-style-span\" face=\"'DejaVu Sans Mono'\" style=\"font-size: large; \">vultures, for so</font><font class=\"Apple-style-span\" size=\"4\"> were the counsels of Jove fulfilled from the day on which the son of Atr</font><font class=\"Apple-style-span\" face=\"BrowalliaUPC\" size=\"3\">eus, king of men, and great A</font><font class=\"Apple-style-span\" size=\"4\">chilles, first fell out with one another.\";</font></h5><p><br></p></div></body></html>"; 999 final static Timeout ZERO_TIMEOUT = new Timeout("KbdType", 0); 1000 final static String ALIGNMENT_TEXT = "Line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1\n" 1001 + "Line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2\n" 1002 + "Line 3 line 3 line 3 line 3 line 3 line 3 line 3\n" 1003 + "Line 4 line 4 line 4 line 4 line 4 line 4\n" 1004 + "Line 5 line 5 line 5 line 5 line 5\n" 1005 + "Line 6 line 6 line 6 line 6\n" 1006 + "Sing, O goddess, the anger of Achilles son of Peleus, that brought countless ills upon the Achaeans. Many a brave soul did it send hurrying down to Hades, and many a hero did it yield a prey to dogs and vultures, for so were the counsels of Jove fulfilled from the day on which the son of Atreus, king of men, and great Achilles, first fell out with one another."; 1007 final static String LIST = "Line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1 line 1\n" 1008 + "Line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2 line 2\n" 1009 + "Line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3 line 3\n" 1010 + "Line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4 line 4\n" 1011 + "Line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5 line 5\n" 1012 + "Line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6 line 6\n"; 1013 final static int SHORT_LIST_LENTGTH = 4; 1014 final static int HEADING1 = 1; 1015 final static int HEADING2 = 2; 1016 final static int HEADING6 = 6; 1017 final static int XX_LARGE_FONT_SIZE = 6; 1018 final static String SHORT_LIST = "Line 1\n" 1019 + "Line 2\n" 1020 + "Line 3\n" 1021 + "Line 4\n"; 1022 final static String LINE = "Item 01 item 02 item 03 item 04 item 05 item 06 item 07 item 08 item 09 item 10 item 11"; 1023 }