Inez has uploaded a new change for review. https://gerrit.wikimedia.org/r/68605
Change subject: Initial import of Selenium tests and Chrome WebDriver for MacOS. ...................................................................... Initial import of Selenium tests and Chrome WebDriver for MacOS. Change-Id: Ib79ed70c21eead5d6cd612f772f90270b9422cb7 --- A modules/ve/test/selenium/chromedriver A modules/ve/test/selenium/pom.xml A modules/ve/test/selenium/src/test/java/BaseTest.java A modules/ve/test/selenium/src/test/java/BasicTests.java A modules/ve/test/selenium/src/test/java/Range.java A modules/ve/test/selenium/src/test/java/testSuite.xml 6 files changed, 310 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor refs/changes/05/68605/1 diff --git a/modules/ve/test/selenium/chromedriver b/modules/ve/test/selenium/chromedriver new file mode 100755 index 0000000..1a8372f --- /dev/null +++ b/modules/ve/test/selenium/chromedriver Binary files differ diff --git a/modules/ve/test/selenium/pom.xml b/modules/ve/test/selenium/pom.xml new file mode 100755 index 0000000..b733df3 --- /dev/null +++ b/modules/ve/test/selenium/pom.xml @@ -0,0 +1,47 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.mw</groupId> + <artifactId>VE-tests</artifactId> + <version>0.0.1-SNAPSHOT</version> + <name>VE-tests</name> + <dependencies> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <version>6.8</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.seleniumhq.selenium</groupId> + <artifactId>selenium-java</artifactId> + <version>2.33.0</version> + </dependency> + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-mapper-asl</artifactId> + <version>1.9.12</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.14.1</version> + <configuration> + <systemPropertyVariables> + <browser>${browser}</browser> + </systemPropertyVariables> + <suiteXmlFiles> + <suiteXmlFile>src/test/java/testSuite.xml</suiteXmlFile> + </suiteXmlFiles> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/modules/ve/test/selenium/src/test/java/BaseTest.java b/modules/ve/test/selenium/src/test/java/BaseTest.java new file mode 100755 index 0000000..ab08a7f --- /dev/null +++ b/modules/ve/test/selenium/src/test/java/BaseTest.java @@ -0,0 +1,105 @@ +import org.codehaus.jackson.map.ObjectMapper; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; + +public abstract class BaseTest { + + protected WebDriver driver; + + protected WebElement documentNode; + + protected ObjectMapper mapper = new ObjectMapper(); + + @BeforeClass + public void setUp() { + driver = new ChromeDriver(); + //driver = new FirefoxDriver(); + driver.get("http://192.168.142.128/mw/extensions/VisualEditor/demos/ve/?page=simple"); + documentNode = driver.findElement(By.className("ve-ce-documentNode")); + } + + @AfterClass + public void tearDown() { + driver.close(); + } + + protected void showSelection(int at) { + showSelection(at, at); + } + + protected void showSelection(int from, int to) { + String showSelectiontJS = "ve.instances[0].model.change( null, new ve.Range( " + from + ", " + to + " ) );"; + ((JavascriptExecutor) driver).executeScript(showSelectiontJS); + } + + protected void emptyDocument() { + String emptyDocumentJS = + "ve.instances[0].model.change(" + + "ve.dm.Transaction.newFromRemoval(" + + "ve.instances[0].model.documentModel," + + "new ve.Range( 0, ve.instances[0].model.documentModel.data.getLength() )" + + ")" + + ");"; + ((JavascriptExecutor) driver).executeScript(emptyDocumentJS); + } + + protected void loadDocument(String html) { + emptyDocument(); + String loadDocumentJS = + "var doc = new ve.dm.Document( [] );" + + "var store = doc.getStore();" + + "var internalList = doc.getInternalList();" + + "var data = ve.dm.converter.getDataFromDom( ve.createDocumentFromHtml( '" + html + "' ), store, internalList ).getData();" + + "ve.instances[0].model.change( ve.dm.Transaction.newFromInsertion( ve.instances[0].model.documentModel, 0, data ) );"; + ((JavascriptExecutor) driver).executeScript(loadDocumentJS); + } + + protected String getHtmlSummaryFromHtml(String html) { + String js = + "return JSON.stringify(" + + "ve.getDomElementSummary( ve.createDocumentFromHtml( '" + html + "' ) )" + + ");"; + return (String) ((JavascriptExecutor) driver).executeScript(js); + + } + + protected String getHtmlSummaryFromEditor() { + String js = + "return JSON.stringify(" + + "ve.getDomElementSummary(" + + "ve.dm.converter.getDomFromData(" + + "ve.instances[0].model.documentModel.getFullData()," + + "ve.instances[0].model.documentModel.getStore()," + + "ve.instances[0].model.documentModel.getInternalList()" + + ")" + + ")"+ + ");"; + return (String) ((JavascriptExecutor) driver).executeScript(js); + } + + protected Range getSelection() throws Exception { + String selectionString = (String) ((JavascriptExecutor) driver).executeScript("return JSON.stringify(ve.instances[0].model.selection);"); + return mapper.readValue(selectionString, Range.class); + } + + protected void assertEqualsJson(String actualJson, String expectedJson) throws Exception { + /* + System.out.println("------------------"); + System.out.println("actualJson" + actualJson); + System.out.println("------------------"); + System.out.println("expectedJson" + expectedJson); + System.out.println("------------------"); + */ + Object actual = mapper.readValue(actualJson, Object.class); + Object expected = mapper.readValue(expectedJson, Object.class); + Assert.assertEquals(actual, expected); + } + +} \ No newline at end of file diff --git a/modules/ve/test/selenium/src/test/java/BasicTests.java b/modules/ve/test/selenium/src/test/java/BasicTests.java new file mode 100755 index 0000000..89fc160 --- /dev/null +++ b/modules/ve/test/selenium/src/test/java/BasicTests.java @@ -0,0 +1,140 @@ +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.testng.Assert; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.Test; + +@Test +public class BasicTests extends BaseTest { + + /* + @AfterMethod + public void aaa() throws Exception { + Thread.sleep(2500); + } + */ + + @Test(groups={"BasicTests"}) + public void insertTextByTypingIntoEmptyDocument() throws Exception { + emptyDocument(); + showSelection(0); + documentNode.sendKeys("Hello world! What are you up to?"); + documentNode.sendKeys(Keys.ESCAPE); + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 33); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><p>Hello world! What are you up to?</p></body></html>") + ); + + } + + @Test(groups={"BasicTests"}) + public void insertTextByTypingIntoNotEmptyDocument() throws Exception { + loadDocument("<html><body><p>Lorem</p></body></html>"); + showSelection(6); + documentNode.sendKeys(" ipsum dolor sit amet."); + documentNode.sendKeys(Keys.ESCAPE); + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 28); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><p>Lorem ipsum dolor sit amet.</p></body></html>") + ); + } + + @Test(groups={"BasicTests"}) + public void breakParagraphWithEnter() throws Exception { + loadDocument("<html><body><p>Lorem ipsum dolor sit amet.</p></body></html>"); + showSelection(12); + documentNode.sendKeys(Keys.RETURN); // break after "Lorem ipsum" + documentNode.sendKeys(Keys.ESCAPE); + showSelection(20); + documentNode.sendKeys(Keys.RETURN);// break after "dolor" + documentNode.sendKeys(Keys.ESCAPE); + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 22); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><p>Lorem ipsum</p><p> dolor</p><p> sit amet.</p></body></html>") + ); + } + + @Test(groups={"BasicTests"}) + public void breakListItemWithEnter() throws Exception { + loadDocument("<html><body><ul><li>item1item2item3</li></ul></body></html>"); + showSelection(8); + documentNode.sendKeys(Keys.RETURN); // break after "item1" + documentNode.sendKeys(Keys.ESCAPE); + showSelection(17); + documentNode.sendKeys(Keys.RETURN); // break after "item2" + documentNode.sendKeys(Keys.ESCAPE); + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 21); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><ul><li>item1</li><li><p>item2</p></li><li><p>item3</p></li></ul></body></html>") + ); + } + + @Test(groups={"BasicTests"}) + public void exitListWithDoubleReturn() throws Exception { + loadDocument("<html><body><ul><li>item1</li><li>item2</li><li>item3</li></ul></body></html>"); + showSelection(26); + documentNode.sendKeys(Keys.RETURN); + documentNode.sendKeys(Keys.ESCAPE); + documentNode.sendKeys(Keys.RETURN); + documentNode.sendKeys(Keys.ESCAPE); + documentNode.sendKeys("Bye!"); + documentNode.sendKeys(Keys.ESCAPE); + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 34); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><ul><li>item1</li><li>item2</li><li>item3</li></ul><p>Bye!</p></body></html>") + ); + } + + @Test(groups={"BasicTests"}) + public void preAnnotationsWithTyping() throws Exception { + WebElement boldButton = driver.findElement(By.className("ve-ui-icon-bold-b")); + loadDocument("<html><body><p>ipsumsit</p></body></html>"); + showSelection(1); + boldButton.click(); + documentNode.sendKeys("Lorem "); + showSelection(12); + boldButton.click(); + documentNode.sendKeys(" dolor "); + showSelection(22); + boldButton.click(); + documentNode.sendKeys(" amet."); + + Range range = getSelection(); + Assert.assertTrue(range.isCollapsed()); + Assert.assertEquals(range.from, 28); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><p><b>Lorem </b>ipsum<b> dolor </b>sit<b> amet.</b></p></body></html>") + ); + } + + // https://bugzilla.wikimedia.org/show_bug.cgi?id=43082 + @Test(groups={"BasicTests"}) + public void moveCursorNativelyAndBreak() throws Exception { + loadDocument("<html><body><p>This!</p></body></html>"); + showSelection(5); + documentNode.sendKeys(Keys.HOME); + documentNode.sendKeys(Keys.RETURN); + assertEqualsJson( + getHtmlSummaryFromEditor(), + getHtmlSummaryFromHtml("<html><body><p></p><p>This!</p></body></html>") + ); + } + +} \ No newline at end of file diff --git a/modules/ve/test/selenium/src/test/java/Range.java b/modules/ve/test/selenium/src/test/java/Range.java new file mode 100755 index 0000000..5512e6b --- /dev/null +++ b/modules/ve/test/selenium/src/test/java/Range.java @@ -0,0 +1,10 @@ + +public class Range { + public int from; + public int to; + public int start; + public int end; + public boolean isCollapsed() { + return from == to; + } +} diff --git a/modules/ve/test/selenium/src/test/java/testSuite.xml b/modules/ve/test/selenium/src/test/java/testSuite.xml new file mode 100755 index 0000000..f8b4e19 --- /dev/null +++ b/modules/ve/test/selenium/src/test/java/testSuite.xml @@ -0,0 +1,8 @@ +<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" > +<suite name="VE-tests"> + <test name="testing" preserve-order="true"> + <classes> + <class name="BasicTests"/> + </classes> + </test> +</suite> \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/68605 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib79ed70c21eead5d6cd612f772f90270b9422cb7 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Inez <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
