Adds functions for skipping child component layout measuring. Removes unnecessary code from VScrollTable. 1. case: no components - render time without the fix: ~105ms - render time with fix: ~105ms 2. case: 2 button and 2 textfield cols - render time without the fix: ~279ms - render time with fix: ~240ms (~17% faster) 3. case: 3 button and 3 textfield cols - render time without the fix: ~350ms - render time with fix: ~281ms (~20% faster) Change-Id: I6025f8ee2fd438d228ff3b65f43535961cf12c0btags/7.6.0.beta2
@@ -0,0 +1,72 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.client; | |||
import com.vaadin.client.ui.ManagedLayout; | |||
import com.vaadin.client.ui.layout.ElementResizeListener; | |||
/** | |||
* Connector with layout measuring hint. Used to improve granularity of control | |||
* over child component measurements. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface HasChildMeasurementHintConnector extends | |||
HasComponentsConnector { | |||
/** | |||
* Specifies how you would like child components measurements to be handled. | |||
* Since this is a hint, it can be ignored when deemed necessary. | |||
*/ | |||
public enum ChildMeasurementHint { | |||
/** | |||
* Always measure all child components (default). | |||
*/ | |||
MEASURE_ALWAYS, | |||
/** | |||
* Measure child component only if child component is a {@link Layout} | |||
* or implements either {@link ManagedLayout} or | |||
* {@link ElementResizeListener}. | |||
*/ | |||
MEASURE_IF_NEEDED, | |||
/** | |||
* Never measure child components. This can improve rendering speed of | |||
* components with lots of children (e.g. Table), but can cause some | |||
* child components to be rendered incorrectly (e.g. ComboBox). | |||
*/ | |||
MEASURE_NEVER | |||
} | |||
/** | |||
* Sets the child measurement hint for this component. | |||
* | |||
* @param hint | |||
* the value to set | |||
*/ | |||
void setChildMeasurementHint(ChildMeasurementHint hint); | |||
/** | |||
* Returns the current child measurement hint value. | |||
* | |||
* @return a ChildLayoutMeasureMode value | |||
*/ | |||
ChildMeasurementHint getChildMeasurementHint(); | |||
} |
@@ -712,7 +712,8 @@ public class LayoutManager { | |||
.createArray().cast(); | |||
for (int i = 0; i < size; i++) { | |||
ComponentConnector candidate = allConnectors.get(i); | |||
if (needsMeasure(candidate.getWidget().getElement())) { | |||
if (!Util.shouldSkipMeasurementOfConnector(candidate) | |||
&& needsMeasure(candidate.getWidget().getElement())) { | |||
connectors.add(candidate); | |||
} | |||
} |
@@ -33,8 +33,12 @@ import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Event; | |||
import com.google.gwt.user.client.ui.HasWidgets; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.HasChildMeasurementHintConnector.ChildMeasurementHint; | |||
import com.vaadin.client.RenderInformation.FloatSize; | |||
import com.vaadin.client.ui.AbstractLayoutConnector; | |||
import com.vaadin.client.ui.ManagedLayout; | |||
import com.vaadin.client.ui.VOverlay; | |||
import com.vaadin.client.ui.layout.ElementResizeListener; | |||
import com.vaadin.shared.AbstractComponentState; | |||
import com.vaadin.shared.ApplicationConstants; | |||
import com.vaadin.shared.communication.MethodInvocation; | |||
@@ -1186,6 +1190,83 @@ public class Util { | |||
return +(Math.round(num + "e+" + exp) + "e-" + exp); | |||
}-*/; | |||
/** | |||
* Test if we can can skip measuring this connector. We can skip the | |||
* measurement if its parent is a ChildMeasureHintConnector and has an | |||
* appropriate mode set. | |||
* | |||
* For internal use only. May be removed or replaced in the future. | |||
*/ | |||
public static boolean shouldSkipMeasurementOfConnector( | |||
ComponentConnector candidate, ComponentConnector parent) { | |||
Profiler.enter("skipMeasureDueLayoutHint"); | |||
boolean skip = false; | |||
if (parent instanceof HasChildMeasurementHintConnector) { | |||
ChildMeasurementHint measureMode = ((HasChildMeasurementHintConnector) parent) | |||
.getChildMeasurementHint(); | |||
if (measureMode == ChildMeasurementHint.MEASURE_NEVER) { | |||
skip = true; | |||
} else if (measureMode == ChildMeasurementHint.MEASURE_IF_NEEDED) { | |||
skip = canWeSkipChildMeasurement(candidate); | |||
} | |||
} | |||
Profiler.leave("skipMeasureDueLayoutHint"); | |||
return skip; | |||
} | |||
/** | |||
* Test if we can can skip measuring this connector. We can skip the | |||
* measurement if its parent is a ChildMeasureHintConnector and has an | |||
* appropriate mode set. | |||
* | |||
* This version of the method tries to recursively locate such a parent. | |||
* | |||
* For internal use only. May be removed or replaced in the future. | |||
*/ | |||
public static boolean shouldSkipMeasurementOfConnector( | |||
ComponentConnector candidate) { | |||
Profiler.enter("skipMeasureDueLayoutHint"); | |||
boolean skip = false; | |||
HasChildMeasurementHintConnector parent = getPossibleChildMeasurementHintParentConnector(candidate); | |||
if (parent != null) { | |||
ChildMeasurementHint measureMode = parent.getChildMeasurementHint(); | |||
if (measureMode == ChildMeasurementHint.MEASURE_NEVER) { | |||
skip = true; | |||
} else if (measureMode == ChildMeasurementHint.MEASURE_IF_NEEDED) { | |||
skip = canWeSkipChildMeasurement(candidate); | |||
} | |||
} | |||
Profiler.leave("skipMeasureDueLayoutHint"); | |||
return skip; | |||
} | |||
/** For internal use only. May be removed or replaced in the future. */ | |||
private static boolean canWeSkipChildMeasurement(ComponentConnector child) { | |||
// common cases when child measuring is possibly needed | |||
if (child instanceof ElementResizeListener | |||
|| child instanceof ManagedLayout | |||
|| child instanceof AbstractLayoutConnector) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** For internal use only. May be removed or replaced in the future. */ | |||
private static HasChildMeasurementHintConnector getPossibleChildMeasurementHintParentConnector( | |||
ComponentConnector candidate) { | |||
ServerConnector parent = candidate.getParent(); | |||
if (parent != null | |||
&& parent instanceof HasChildMeasurementHintConnector) { | |||
return (HasChildMeasurementHintConnector) parent; | |||
} | |||
return null; | |||
} | |||
private static Logger getLogger() { | |||
return Logger.getLogger(Util.class.getName()); | |||
} |
@@ -84,6 +84,7 @@ import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ConnectorMap; | |||
import com.vaadin.client.DeferredWorker; | |||
import com.vaadin.client.Focusable; | |||
import com.vaadin.client.HasChildMeasurementHintConnector.ChildMeasurementHint; | |||
import com.vaadin.client.MouseEventDetailsBuilder; | |||
import com.vaadin.client.StyleConstants; | |||
import com.vaadin.client.TooltipInfo; | |||
@@ -699,6 +700,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
private int multiselectmode; | |||
/** | |||
* Hint for how to handle measurement of child components | |||
*/ | |||
private ChildMeasurementHint childMeasurementHint = ChildMeasurementHint.MEASURE_ALWAYS; | |||
/** For internal use only. May be removed or replaced in the future. */ | |||
public int tabIndex; | |||
@@ -1238,11 +1244,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
uidl.getIntAttribute("rows")); | |||
scrollBodyPanel.add(scrollBody); | |||
// New body starts scrolled to the left, make sure the header and footer | |||
// are also scrolled to the left | |||
tHead.setHorizontalScrollPosition(0); | |||
tFoot.setHorizontalScrollPosition(0); | |||
initialContentReceived = true; | |||
sizeNeedsInit = true; | |||
scrollBody.restoreRowVisibility(); | |||
@@ -2620,8 +2621,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
@Override | |||
public void run() { | |||
if (client.getMessageSender().hasActiveRequest() | |||
|| navKeyDown) { | |||
if (client.getMessageSender().hasActiveRequest() || navKeyDown) { | |||
// if client connection is busy, don't bother loading it more | |||
VConsole.log("Postponed rowfetch"); | |||
schedule(250); | |||
@@ -8332,4 +8332,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, | |||
private static Logger getLogger() { | |||
return Logger.getLogger(VScrollTable.class.getName()); | |||
} | |||
public ChildMeasurementHint getChildMeasurementHint() { | |||
return childMeasurementHint; | |||
} | |||
public void setChildMeasurementHint(ChildMeasurementHint hint) { | |||
childMeasurementHint = hint; | |||
} | |||
} |
@@ -248,7 +248,8 @@ public class LayoutDependencyTree { | |||
if (connector instanceof HasComponentsConnector) { | |||
HasComponentsConnector container = (HasComponentsConnector) connector; | |||
for (ComponentConnector child : container.getChildComponents()) { | |||
if (isRelativeInDirection(child, direction)) { | |||
if (!Util.shouldSkipMeasurementOfConnector(child, connector) | |||
&& isRelativeInDirection(child, direction)) { | |||
resized.push(child.getConnectorId()); | |||
} | |||
} |
@@ -28,6 +28,7 @@ import com.google.gwt.event.shared.HandlerRegistration; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.ApplicationConnection; | |||
import com.vaadin.client.BrowserInfo; | |||
import com.vaadin.client.HasChildMeasurementHintConnector; | |||
import com.vaadin.client.ComponentConnector; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent; | |||
import com.vaadin.client.ConnectorHierarchyChangeEvent.ConnectorHierarchyChangeHandler; | |||
@@ -55,7 +56,7 @@ import com.vaadin.shared.ui.table.TableState; | |||
@Connect(com.vaadin.ui.Table.class) | |||
public class TableConnector extends AbstractFieldConnector implements | |||
HasComponentsConnector, ConnectorHierarchyChangeHandler, Paintable, | |||
DirectionalManagedLayout, PostLayoutListener { | |||
DirectionalManagedLayout, PostLayoutListener, HasChildMeasurementHintConnector { | |||
private List<ComponentConnector> childComponents; | |||
@@ -199,6 +200,12 @@ public class TableConnector extends AbstractFieldConnector implements | |||
getWidget().updateDragMode(uidl); | |||
// Update child measure hint | |||
int childMeasureHint = uidl.hasAttribute("measurehint") ? uidl | |||
.getIntAttribute("measurehint") : 0; | |||
getWidget().setChildMeasurementHint( | |||
ChildMeasurementHint.values()[childMeasureHint]); | |||
getWidget().updateSelectionProperties(uidl, getState(), isReadOnly()); | |||
if (uidl.hasAttribute("alb")) { | |||
@@ -532,4 +539,14 @@ public class TableConnector extends AbstractFieldConnector implements | |||
ConnectorHierarchyChangeEvent.TYPE, handler); | |||
} | |||
@Override | |||
public void setChildMeasurementHint(ChildMeasurementHint hint) { | |||
getWidget().setChildMeasurementHint(hint); | |||
} | |||
@Override | |||
public ChildMeasurementHint getChildMeasurementHint() { | |||
return getWidget().getChildMeasurementHint(); | |||
} | |||
} |
@@ -0,0 +1,69 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.ui; | |||
/** | |||
* Component with layout measuring hint. Used to improve granularity of control | |||
* over child component measurements. | |||
* | |||
* @since | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface HasChildMeasurementHint extends HasComponents { | |||
/** | |||
* Specifies how you would like child components measurements to be handled. | |||
* Since this is a hint, it can be ignored when deemed necessary. | |||
*/ | |||
public enum ChildMeasurementHint { | |||
/** | |||
* Always measure all child components (default). | |||
*/ | |||
MEASURE_ALWAYS, | |||
/** | |||
* Measure child component only if child component is a Layout or | |||
* implements either ManagedLayout or ElementResizeListener. | |||
*/ | |||
MEASURE_IF_NEEDED, | |||
/** | |||
* Never measure child components. This can improve rendering speed of | |||
* components with lots of children (e.g. Table), but can cause some | |||
* child components to be rendered incorrectly (e.g. ComboBox). | |||
*/ | |||
MEASURE_NEVER | |||
} | |||
/** | |||
* Sets desired child size measurement hint. | |||
* | |||
* @param hint | |||
* desired hint. A value of null will reset value back to the | |||
* default (MEASURE_ALWAYS) | |||
*/ | |||
void setChildMeasurementHint(ChildMeasurementHint hint); | |||
/** | |||
* Returns the current child size measurement hint. | |||
* | |||
* @return a child measurement hint value | |||
*/ | |||
ChildMeasurementHint getChildMeasurementHint(); | |||
} |
@@ -100,7 +100,7 @@ import com.vaadin.util.ReflectTools; | |||
@SuppressWarnings({ "deprecation" }) | |||
public class Table extends AbstractSelect implements Action.Container, | |||
Container.Ordered, Container.Sortable, ItemClickNotifier, DragSource, | |||
DropTarget, HasComponents { | |||
DropTarget, HasComponents, HasChildMeasurementHint { | |||
private transient Logger logger = null; | |||
@@ -357,6 +357,11 @@ public class Table extends AbstractSelect implements Action.Container, | |||
private static final Object ROW_HEADER_FAKE_PROPERTY_ID = new UniqueSerializable() { | |||
}; | |||
/** | |||
* How layout manager should behave when measuring Table's child components | |||
*/ | |||
private ChildMeasurementHint childMeasurementHint = ChildMeasurementHint.MEASURE_ALWAYS; | |||
/* Private table extensions to Select */ | |||
/** | |||
@@ -3542,6 +3547,7 @@ public class Table extends AbstractSelect implements Action.Container, | |||
paintTabIndex(target); | |||
paintDragMode(target); | |||
paintSelectMode(target); | |||
paintTableChildLayoutMeasureMode(target); | |||
if (cacheRate != CACHE_RATE_DEFAULT) { | |||
target.addAttribute("cr", cacheRate); | |||
@@ -3882,6 +3888,11 @@ public class Table extends AbstractSelect implements Action.Container, | |||
} | |||
} | |||
private void paintTableChildLayoutMeasureMode(PaintTarget target) | |||
throws PaintException { | |||
target.addAttribute("measurehint", getChildMeasurementHint().ordinal()); | |||
} | |||
/** | |||
* Checks whether row headers are visible. | |||
* | |||
@@ -6467,4 +6478,18 @@ public class Table extends AbstractSelect implements Action.Container, | |||
} | |||
return logger; | |||
} | |||
@Override | |||
public void setChildMeasurementHint(ChildMeasurementHint hint) { | |||
if (hint == null) { | |||
childMeasurementHint = ChildMeasurementHint.MEASURE_ALWAYS; | |||
} else { | |||
childMeasurementHint = hint; | |||
} | |||
} | |||
@Override | |||
public ChildMeasurementHint getChildMeasurementHint() { | |||
return childMeasurementHint; | |||
} | |||
} |
@@ -0,0 +1,184 @@ | |||
package com.vaadin.tests.components.table; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.AbstractOrderedLayout; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.Button.ClickListener; | |||
import com.vaadin.ui.ComboBox; | |||
import com.vaadin.ui.DateField; | |||
import com.vaadin.ui.GridLayout; | |||
import com.vaadin.ui.HasChildMeasurementHint.ChildMeasurementHint; | |||
import com.vaadin.ui.HorizontalLayout; | |||
import com.vaadin.ui.Label; | |||
import com.vaadin.ui.Table; | |||
import com.vaadin.ui.TextField; | |||
public class TableChildMeasurementHint extends AbstractTestUI { | |||
private HorizontalLayout buttonLayout = new HorizontalLayout(); | |||
private HorizontalLayout layout; | |||
private Table table1, table2, table3; | |||
@Override | |||
public void setup(VaadinRequest request) { | |||
initMain(); | |||
} | |||
protected void initMain() { | |||
((AbstractOrderedLayout) getContent()).setMargin(false); | |||
layout = new HorizontalLayout(); | |||
layout.setSpacing(true); | |||
layout.setMargin(false); | |||
layout.setSizeFull(); | |||
addComponent(buttonLayout); | |||
addComponent(layout); | |||
table1 = createTable(); | |||
table1.setSizeFull(); | |||
table1.setChildMeasurementHint(ChildMeasurementHint.MEASURE_ALWAYS); | |||
table2 = createTable(); | |||
table2.setSizeFull(); | |||
table2.setChildMeasurementHint(ChildMeasurementHint.MEASURE_IF_NEEDED); | |||
table3 = createTable(); | |||
table3.setSizeFull(); | |||
table3.setChildMeasurementHint(ChildMeasurementHint.MEASURE_NEVER); | |||
buttonLayout.addComponent(new Button("Show table1", | |||
new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
layout.addComponent(table1); | |||
table1.focus(); | |||
} | |||
})); | |||
buttonLayout.addComponent(new Button("Show table2", | |||
new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
layout.removeComponent(table1); | |||
layout.addComponent(table2); | |||
table2.focus(); | |||
} | |||
})); | |||
buttonLayout.addComponent(new Button("Show table3", | |||
new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
layout.removeComponent(table2); | |||
layout.addComponent(table3); | |||
table3.focus(); | |||
} | |||
})); | |||
} | |||
protected Table createTable() { | |||
Table table = new Table(); | |||
table.setSelectable(true); | |||
table.setPageLength(39); | |||
for (int i = 0; i < 5; i++) { | |||
table.addContainerProperty("First_Name" + i, String.class, null); | |||
table.addContainerProperty("Last Name" + i, String.class, null); | |||
table.addContainerProperty("Year" + i, Integer.class, null); | |||
} | |||
/* Add a few items in the table. */ | |||
int j = 0; | |||
for (int i = 0; i < 2; i++) { | |||
table.addItem( | |||
makeRow(new Object[] { "Nicolaus" + i, "Copernicus", 1473 }, | |||
5), j++); | |||
table.addItem( | |||
makeRow(new Object[] { "Tycho" + i, "Brahe", 1546 }, 5), | |||
j++); | |||
table.addItem( | |||
makeRow(new Object[] { "Giordano" + i, "Bruno", 1548 }, 5), | |||
j++); | |||
table.addItem( | |||
makeRow(new Object[] { "Galileo" + i, "Galilei", 1564 }, 5), | |||
j++); | |||
table.addItem( | |||
makeRow(new Object[] { "Johannes" + i, "Kepler", 1571 }, 5), | |||
j++); | |||
table.addItem( | |||
makeRow(new Object[] { "Isaac" + i, "Newton", 1643 }, 5), | |||
j++); | |||
} | |||
table.addGeneratedColumn("First_Name" + 0, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
ComboBox b = new ComboBox("ComboBox"); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
table.addGeneratedColumn("First_Name" + 1, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
GridLayout b = new GridLayout(); | |||
b.addComponents(new Label("l1"), new Button("b"), new Label( | |||
"l2")); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
table.addGeneratedColumn("First_Name" + 2, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
Button b = new Button("Button"); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
table.addGeneratedColumn("First_Name" + 3, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
TextField b = new TextField("Textfield"); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
table.addGeneratedColumn("First_Name" + 4, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
DateField b = new DateField("DateField"); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
table.addGeneratedColumn("First_Name" + 5, new Table.ColumnGenerator() { | |||
@Override | |||
public Object generateCell(Table components, Object o, Object o2) { | |||
Label b = new Label("Label"); | |||
b.setWidthUndefined(); | |||
return b; | |||
} | |||
}); | |||
return table; | |||
} | |||
protected Object[] makeRow(Object[] data, int c) { | |||
Object[] row = new Object[c * data.length]; | |||
for (int j = 0; j < c; j++) { | |||
int x = 0; | |||
for (Object value : data) { | |||
row[j * data.length + x] = value; | |||
x++; | |||
} | |||
} | |||
return row; | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* Copyright 2000-2014 Vaadin Ltd. | |||
* | |||
* Licensed 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 com.vaadin.tests.components.table; | |||
import java.io.IOException; | |||
import org.junit.Test; | |||
import com.vaadin.testbench.elements.ButtonElement; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class TableChildMeasurementHintTest extends MultiBrowserTest { | |||
@Test | |||
public void testCacheSize() throws IOException { | |||
openTestURL(); | |||
$(ButtonElement.class).first().click(); | |||
compareScreen("initial"); | |||
$(ButtonElement.class).get(1).click(); | |||
compareScreen("initial"); | |||
$(ButtonElement.class).get(2).click(); | |||
compareScreen("initial"); | |||
} | |||
} |