Skip to content

Commit 16b968e

Browse files
committed
Merge remote-tracking branch 'upstream/master' into bootstrapDialogFix
2 parents fe63851 + 9e6ebd8 commit 16b968e

File tree

12 files changed

+226
-78
lines changed

12 files changed

+226
-78
lines changed

docs/rest-api/rest-notebook.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,26 @@ limitations under the License.
9292
<td> 500 </td>
9393
</tr>
9494
<tr>
95-
<td> sample JSON input </td>
96-
<td><pre>{"name": "name of new notebook"}</pre></td>
95+
<td> sample JSON input (without paragraphs) </td>
96+
<td><pre>{ "name": "name of new notebook" }</pre></td>
97+
</tr>
98+
<tr>
99+
<td> sample JSON input (with initial paragraphs) </td>
100+
<td><pre>
101+
{
102+
"name": "name of new notebook",
103+
"paragraphs": [
104+
{
105+
"title": "paragraph title1",
106+
"text": "paragraph text1"
107+
},
108+
{
109+
"title": "paragraph title2",
110+
"text": "paragraph text2"
111+
}
112+
]
113+
}
114+
</pre></td>
97115
</tr>
98116
<tr>
99117
<td> sample JSON response </td>

zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@
3030
import org.apache.zeppelin.notebook.Note;
3131
import org.apache.zeppelin.notebook.Notebook;
3232
import org.apache.zeppelin.notebook.Paragraph;
33-
import org.apache.zeppelin.rest.message.CronRequest;
34-
import org.apache.zeppelin.rest.message.InterpreterSettingListForNoteBind;
35-
import org.apache.zeppelin.rest.message.NewInterpreterSettingRequest;
36-
import org.apache.zeppelin.rest.message.NewNotebookRequest;
33+
import org.apache.zeppelin.rest.message.*;
3734
import org.apache.zeppelin.server.JsonResponse;
3835
import org.apache.zeppelin.server.ZeppelinServer;
3936
import org.apache.zeppelin.socket.NotebookServer;
@@ -138,7 +135,15 @@ public Response createNote(String message) throws IOException {
138135
NewNotebookRequest request = gson.fromJson(message,
139136
NewNotebookRequest.class);
140137
Note note = notebook.createNote();
141-
note.addParagraph(); // it's an empty note. so add one paragraph
138+
List<NewParagraphRequest> initialParagraphs = request.getParagraphs();
139+
if (initialParagraphs != null) {
140+
for (NewParagraphRequest paragraphRequest : initialParagraphs) {
141+
Paragraph p = note.addParagraph();
142+
p.setTitle(paragraphRequest.getTitle());
143+
p.setText(paragraphRequest.getText());
144+
}
145+
}
146+
note.addParagraph(); // add one paragraph to the last
142147
String noteName = request.getName();
143148
if (noteName.isEmpty()) {
144149
noteName = "Note " + note.getId();

zeppelin-server/src/main/java/org/apache/zeppelin/rest/message/NewNotebookRequest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.zeppelin.rest.message;
1919

20+
import java.util.List;
2021
import java.util.Map;
2122

2223
import org.apache.zeppelin.interpreter.InterpreterOption;
@@ -27,6 +28,7 @@
2728
*/
2829
public class NewNotebookRequest {
2930
String name;
31+
List<NewParagraphRequest> paragraphs;
3032

3133
public NewNotebookRequest (){
3234

@@ -35,4 +37,8 @@ public NewNotebookRequest (){
3537
public String getName() {
3638
return name;
3739
}
40+
41+
public List<NewParagraphRequest> getParagraphs() {
42+
return paragraphs;
43+
}
3844
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.rest.message;
19+
20+
/**
21+
* NewParagraphRequest rest api request message
22+
*
23+
* It is used for NewNotebookRequest with initial paragraphs
24+
*
25+
*/
26+
public class NewParagraphRequest {
27+
String title;
28+
String text;
29+
30+
public NewParagraphRequest() {
31+
32+
}
33+
34+
public String getTitle() {
35+
return title;
36+
}
37+
38+
public String getText() {
39+
return text;
40+
}
41+
}

zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,57 @@
1717

1818
package org.apache.zeppelin;
1919

20+
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.fail;
22+
23+
import java.io.File;
24+
import java.util.LinkedList;
25+
import java.util.List;
26+
import java.util.concurrent.TimeUnit;
27+
2028
import org.junit.After;
2129
import org.junit.Before;
2230
import org.junit.Test;
23-
import org.openqa.selenium.*;
31+
import org.openqa.selenium.By;
32+
import org.openqa.selenium.ElementNotVisibleException;
33+
import org.openqa.selenium.Keys;
34+
import org.openqa.selenium.NoSuchElementException;
35+
import org.openqa.selenium.OutputType;
36+
import org.openqa.selenium.TakesScreenshot;
37+
import org.openqa.selenium.TimeoutException;
38+
import org.openqa.selenium.WebDriver;
39+
import org.openqa.selenium.WebElement;
2440
import org.openqa.selenium.chrome.ChromeDriver;
2541
import org.openqa.selenium.firefox.FirefoxBinary;
2642
import org.openqa.selenium.firefox.FirefoxDriver;
2743
import org.openqa.selenium.firefox.FirefoxProfile;
2844
import org.openqa.selenium.safari.SafariDriver;
29-
import org.openqa.selenium.support.ui.ExpectedCondition;
3045
import org.openqa.selenium.support.ui.ExpectedConditions;
46+
import org.openqa.selenium.support.ui.FluentWait;
47+
import org.openqa.selenium.support.ui.Wait;
3148
import org.openqa.selenium.support.ui.WebDriverWait;
49+
import org.slf4j.Logger;
50+
import org.slf4j.LoggerFactory;
3251

33-
import java.util.LinkedList;
34-
import java.util.List;
35-
36-
import static org.junit.Assert.assertEquals;
37-
import static org.junit.Assert.fail;
52+
import com.google.common.base.Function;
3853

3954
/**
40-
* Test Zeppelin with web brower.
55+
* Test Zeppelin with web browser.
4156
*
4257
* To test, ZeppelinServer should be running on port 8080
43-
* On OSX, you'll need firefox 42.0 installed.
58+
* On OSX, you'll need firefox 42.0 installed, then you can run with
59+
*
60+
* PATH=~/Applications/Firefox.app/Contents/MacOS/:$PATH CI="" \
61+
* mvn -Dtest=org.apache.zeppelin.ZeppelinIT -Denforcer.skip=true \
62+
* test -pl zeppelin-server
4463
*
4564
*/
4665
public class ZeppelinIT {
66+
private static final Logger LOG = LoggerFactory.getLogger(ZeppelinIT.class);
67+
private static final long MAX_BROWSER_TIMEOUT_SEC = 30;
4768
private WebDriver driver;
4869

49-
private WebDriver getWebDriver() {
50-
WebDriver driver = null;
70+
private void setWebDriver() {
5171

5272
if (driver == null) {
5373
try {
@@ -59,20 +79,23 @@ private WebDriver getWebDriver() {
5979
FirefoxProfile profile = new FirefoxProfile();
6080
driver = new FirefoxDriver(ffox, profile);
6181
} catch (Exception e) {
82+
LOG.error("Starting Firefox failed",e);
6283
}
6384
}
6485

6586
if (driver == null) {
6687
try {
6788
driver = new ChromeDriver();
6889
} catch (Exception e) {
90+
LOG.error("Starting Chrome failed",e);
6991
}
7092
}
7193

7294
if (driver == null) {
7395
try {
7496
driver = new SafariDriver();
7597
} catch (Exception e) {
98+
LOG.error("Starting Safari failed",e);
7699
}
77100
}
78101

@@ -88,16 +111,9 @@ private WebDriver getWebDriver() {
88111
driver.get(url);
89112

90113
while (System.currentTimeMillis() - start < 60 * 1000) {
91-
// wait for page load
92-
try {
93-
(new WebDriverWait(driver, 5)).until(new ExpectedCondition<Boolean>() {
94-
@Override
95-
public Boolean apply(WebDriver d) {
96-
return d.findElement(By.partialLinkText("Create new note"))
97-
.isDisplayed();
98-
}
99-
});
100-
loaded = true;
114+
try { // wait for page load
115+
WebElement element = pollingWait(By.partialLinkText("Create new note"));
116+
loaded = element.isDisplayed();
101117
break;
102118
} catch (TimeoutException e) {
103119
driver.navigate().to(url);
@@ -107,17 +123,14 @@ public Boolean apply(WebDriver d) {
107123
if (loaded == false) {
108124
fail();
109125
}
110-
111-
return driver;
112126
}
113127

114128
@Before
115129
public void startUp() {
116130
if (!endToEndTestEnabled()) {
117131
return;
118132
}
119-
120-
driver = getWebDriver();
133+
setWebDriver();
121134
}
122135

123136
@After
@@ -133,41 +146,45 @@ String getParagraphXPath(int paragraphNo) {
133146
return "//div[@ng-controller=\"ParagraphCtrl\"][" + paragraphNo +"]";
134147
}
135148

136-
void waitForParagraph(final int paragraphNo, final String state) {
137-
(new WebDriverWait(driver, 60)).until(new ExpectedCondition<Boolean>() {
138-
public Boolean apply(WebDriver d) {
139-
return driver.findElement(By.xpath(getParagraphXPath(paragraphNo)
140-
+ "//div[contains(@class, 'control')]//span[1][contains(.,'" + state + "')]"))
141-
.isDisplayed();
142-
}
143-
144-
;
145-
});
146-
}
147-
148-
boolean endToEndTestEnabled() {
149-
return null != System.getenv("CI");
149+
boolean waitForParagraph(final int paragraphNo, final String state) {
150+
By locator = By.xpath(getParagraphXPath(paragraphNo)
151+
+ "//div[contains(@class, 'control')]//span[1][contains(.,'" + state + "')]");
152+
WebElement element = pollingWait(locator);
153+
return element.isDisplayed();
150154
}
151155

152-
boolean waitForText(final String txt, final By by) {
156+
boolean waitForText(final String txt, final By locator) {
153157
try {
154-
new WebDriverWait(driver, 5).until(new ExpectedCondition<Boolean>() {
155-
@Override
156-
public Boolean apply(WebDriver d) {
157-
return txt.equals(driver.findElement(by).getText());
158-
}
159-
});
160-
return true;
158+
WebElement element = pollingWait(locator);
159+
return txt.equals(element.getText());
161160
} catch (TimeoutException e) {
162161
return false;
163162
}
164163
}
165164

165+
public WebElement pollingWait(final By locator) {
166+
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
167+
.withTimeout(MAX_BROWSER_TIMEOUT_SEC, TimeUnit.SECONDS)
168+
.pollingEvery(1, TimeUnit.SECONDS)
169+
.ignoring(NoSuchElementException.class);
170+
171+
return wait.until(new Function<WebDriver, WebElement>() {
172+
public WebElement apply(WebDriver driver) {
173+
return driver.findElement(locator);
174+
}
175+
});
176+
};
177+
178+
boolean endToEndTestEnabled() {
179+
return null != System.getenv("CI");
180+
}
181+
166182
@Test
167183
public void testAngularDisplay() throws InterruptedException{
168184
if (!endToEndTestEnabled()) {
169185
return;
170186
}
187+
try {
171188
createNewNote();
172189

173190
// wait for first paragraph's " READY " status text
@@ -287,6 +304,10 @@ public void testAngularDisplay() throws InterruptedException{
287304
By.xpath(getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
288305

289306
System.out.println("testCreateNotebook Test executed");
307+
} catch (ElementNotVisibleException e) {
308+
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
309+
310+
}
290311
}
291312

292313
private void createNewNote() {
@@ -300,7 +321,7 @@ private void createNewNote() {
300321
WebElement createNoteLink = driver.findElement(By.xpath("//div[contains(@class, \"col-md-4\")]/div/h5/a[contains(.,'Create new note')]"));
301322
createNoteLink.click();
302323

303-
WebDriverWait block = new WebDriverWait(driver, 10);
324+
WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC);
304325
WebElement modal = block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteNameModal")));
305326
WebElement createNoteButton = modal.findElement(By.id("createNoteButton"));
306327
createNoteButton.click();

0 commit comments

Comments
 (0)