New Features of ZATS Mimic 1.1.0

From Documentation
DocumentationSmall Talks2013AprilNew Features of ZATS Mimic 1.1.0
New Features of ZATS Mimic 1.1.0

Author
Hawk Chen, Engineer, Potix Corporation
Date
Released: April 30, 2013
Version
ZATS 1.1.0


Overview

With more powerful testing capabilities, we are glad to release ZATS Mimic 1.1.0. (If you are not familiar with ZATS Mimic, please read introduction to ZATS Mimic for more information.) In this new release, we now support more operations such as upload, download, custom operation and many advanced features including cookie handling, passing arguments to included ZUL, and echo events handling. These features can help you in testing more functions of a ZK application.

New Operations Available

Upload

This version of ZATS Mimic introduces the UploadAgent to simulate file uploading operation supporting single and multiple file uploading simulations. Following are the usage steps:

  1. Obtain an UploadAgent object.
    Depending on your case, you could get it from a Button or from desktop. Note that you should use the same object before calling finish().
  2. Upload a file by invoking upload() method.
  3. Invoke finish() when there are no more files to upload.

Uploading Files for Components with upload attribute

To implement an uploading feature, you can simply use the Fileupload component. Alternatively, you can choose to use a button component such as Button, Menuitem, Toolbarbutton and so on.[1] Then, set true to upload attribute of these components; users can then click and select a file to upload through a browser dialog, as illustrated below:

Application under test

<zk>
	<vbox id="uploadBox" apply="org.zkoss.zats.essentials.UploadComposer">
		<button id="btn" label="button" upload="true" />
		...
	</vbox>
</zk>

Test case

@Test
public void testUploadAttribute() throws Exception {
	File file = getFile();
	DesktopAgent desktop = Zats.newClient().connect("/essentials/upload.zul");
	UploadAgent agent = desktop.query("#btn").as(UploadAgent.class);
	agent.upload(file, "text/plain");
	agent.finish();
	//verify result
}
  • Line 14: Cast a component to UploadAgent and keep its reference.
  • Line 15: Invoke upload() method to upload a file.
  • Line 16: Don't forget to invoke finish()method.

Uploading Files with Fileupload.get()

Another way to implement the uploading feature is to use the static method Fileupload.get() as an event handler.[2] This static method will open up an uploading dialog and allow users to upload single or multiple files (if configured), as shown in the image below:

Application under test

<zk>
	<vbox id="uploadBox" apply="org.zkoss.zats.essentials.UploadComposer">
		...
		<label id="label1" value="click label1 will invoke fileupload.get()" />
		<label id="label2" value="click label2 will invoke fileupload.get(3)" />
		...
	</vbox>
</zk>


In this case, we can retrieve UploadAgent from DesktopAgent. Following is a typical example of file uploading with Fileupload.get():

Test case for uploading

@Test
public void test() throws Exception {
	File[] files = getFiles();
	DesktopAgent desktop = Zats.newClient().connect("/essentials/upload.zul");
	desktop.query("#label2").click();
	UploadAgent agent = desktop.as(UploadAgent.class);
	agent.upload(files[0], "text/plain");
	agent.upload(files[1], "image/png");
	agent.finish();
	//Verify the result
}
  • Line 14-15: After triggering an event leading to an uploading operation, we can cast DesktopAgent as an UploadAgent for uploading.
  • Line 16-17: We can also upload multiple files at once using Fileupload.get().
  • Line 18: Don't forget to invoke finish()method.

Download

We usually implement file downloading through Filedownload when some events are triggered [3]. Following is a simple application with file downloading function:

download.zul

<zk>
	<div apply="org.zkoss.zats.essentials.DownloadComposer">
		<button id="btn" label="download" />
	</div>
</zk>

DownloadComposer.java

public class DownloadComposer extends SelectorComposer<Component>{
	@Listen("onClick=#btn")
	public void download() throws IOException {
		Filedownload.save("/essentials/hello.txt", "application/octet-stream");
	}
}


Download Files in a Test Case

The download mechanism is a process involving two steps. When you invoke save(), the Filedownload simply notifies ZK client engine of the download URL. The ZK client engine then downloads the file according to the referred URL.

In order to simulate the behaviour of the ZK client engine, ZATS Mimic introduces the Resource interface which represents a downloadable resource file saved on the server. General steps for testing a download function are as follows:

  1. perform some operations to trigger the download function, e.g. click a button
  2. check the presence of a downloadable resource through a desktop agent
  3. fetch and verify the information or content of the resource


@Test
public void test() throws Exception {
	DesktopAgent desktop = Zats.newClient().connect("/essentials/download.zul");
	Assert. assertNull (desktop. getDownloadable ());
	desktop.query("#btn").click();
	Resource resource = desktop.getDownloadable();
	Assert.assertNotNull(resource);
	Assert.assertEquals("hello.txt", resource.getName());
	String content = readFileContent(resource.getInputStream());
	Assert.assertEquals("Hello world!", content);
}
  • Line 14: Click the button to trigger the download.
  • Line 15-16: Since ZATS Mimic handles the response from ZK application automatically, we can retrieve current downloadable resource files from DesktopAgent.getDownloadable(). If the method returns a null when attempting to retrieve downloadable resources, it indicates that there are no downloadable resources after the previous operation.
  • Line 17-19: We can get more information from Resource to verify it. The readFileContent() is a utility method that fetches the content of resource files as it strings through the input stream to verify the file content.

Custom Operation

Currently, ZATS Mimic supports many operations of ZK components, however, there are still cases where operations are not yet covered. For example, you create a custom component [4]which receives custom AU requests, or a new ZK component in which Mimic doesn't support yet. In such cases, existing operation agents are not able to help you to test it. Therefore, in ZATS Mimic1.1.0 we introduce a new agent called AuAgent and it can help you perform custom operations with a condition that the custom component must implement a particular interface: Component. You can then simulate your component's custom operations by constructing your custom event data with AuData and send it with AuAgent.post().


Application with custom component

<mycomponent id="my" />


This test case simulates custom operation supported by your custom component and verifies the result.

Test Case

	@Test
	public void test() throws Exception{
		DesktopAgent desktop = Zats.newClient().connect("/essentials/custom.zul");
		ComponentAgent mycomponent = desktop.query("mycomponent");
		AuData myEventData = new AuData("onMyEventName");
		myEventData.setData("mykey", "myvalue").setData("data", 10);
		mycomponent.as(AuAgent.class).post(myEventData);
		//verify result
	}
  • Line 14,15: Construct the data carried by an AU request first, which would depend on how you design the component.
  • Line 16: Like using other operation agents, get AuAgent from the component and invoke post() to perform an operation.

New Advanced Feature

Cookie Handling

In order to provide the handling of HTTP cookies for developers, ZATS Mimic introduces a group of methods on Client. ZATS Mimic seamlessly maintains cookies after connecting with a ZK application; it can read and set the current cookies. Below is a simple application that stores data in the cookie, and we can use Mimic to test it:


Application under test

<zk>
	<div apply="CookieComposer">
		<button id="change" label="change" />
	</div>
</zk>
public class CookieComposer extends SelectorComposer<Component> {
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		setCookie("foo", "bar");
	}

	@Listen("onClick=#change")
	public void change() {
		setCookie("foo", "hello");
	}

	public void setCookie(String name, String value) {
		HttpServletResponse resp = (HttpServletResponse)Executions.getCurrent().getNativeResponse();
		resp.addCookie(new Cookie(name, value));
	}
}
  • Line 13: This will add a cookie at the beginning.
  • Line 16, 18: Changes the cookie from server-side when the user clicks the button.


Test case

@Test
public void Test() {
	Client client = Zats.newClient();
	DesktopAgent desktop = client.connect("/essentials/cookie.zul");
	Assert.assertEquals("bar", client.getCookie("foo"));
	Assert.assertEquals(null, client.getCookie("not existed"));
	desktop.query("#change").click();
	Assert.assertEquals("hello", client.getCookie("foo"));
}
  • Line 13-15: After connecting to a ZUL page, we can get the cookies and verify them.
  • Line 16-17: ZATS Mimic maintains all cookies during any operations.

Test Included ZUL

ZK provides the Include component[5] and Execution.createComponents(String, Component, Map) method[6] to include and/or reuse ZUL pages or others such as a servlet or JSP. In ZATS Mimic, we can directly test ZUL pages which are included by outer pages; simply use the Client.connect(String) method to connect to the ZUL page (like how you would normally do) you want to test.

Sometimes, however, we need to pass arguments which can be retrieved from implicit objects arg to included ZUL pages for flexibility. ZATS Mimic therefore introduces a new connecting method Client.connectAsIncluded(String, Map<String, Object>) with the ability to connect to an included ZUL page with specific arguments. Following is a typical example:


<zk>
	<label id="msg" value="${arg.message}" />
</zk>
  • Line 2: Value is retrieved from implicit variable, arg.


@Test
public void test() {
	Map<String, Object> args = new HashMap<String, Object>();
	args.put("message", "Hello world!");
	Client client = Zats.newClient();
	DesktopAgent desktop = client.connectAsIncluded("/included.zul", args);
	Label msg = desktop.query("#msg").as(Label.class);
	Assert.assertEquals("Hello world!", msg.getValue());
}

Handling Echo Event

Echo event is used to implement long operations. When you send an echo event, the event won't be processed in the current execution. Rather, it is processed in the next AU request sent (echoed back) from the client. In this new release, Mimic Client are now capable of simulating an echo event. By default (IMMEDIATE), Mimic Client sends the echoed AU request immediately after receiving an echo event. In PIGGYBACK mode, Mimic Client will then send custom events back to server together with the next AU request instead of sending it back immediately.

public enum EchoEventMode {

	/** immediately reply custom events back to server when receiving echo events	 */
	IMMEDIATE,

	/** reply custom events back to server when next AU event posting */
	PIGGYBACK
}
  • Line 4: The default mode.

However, you can change the default mode by the method Client.setEchoEventMode(EchoEventMode)

References

Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.