Getting contents of system clipboard on headless linux server for automated testing - awt

I am trying to run some selenium cases on a headless linux system through docker in which the "user" clicks a button that copys text to the system clipboard. When I run this code, I get an error that says "No X11 DISPLAY variable was set, but this program performed an operation which requires it."
I am now running the case using xvfb to account for the lack of X11 Display variable, but the code still does not work. Now, I am getting a nullpointer when trying to access the contents of the system clipboard.
Here is the code that I am running to get the copied text.
String copied = null;
try {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable transferable = clipboard.getContents(null);
DataFlavor[] availableFlavors = clipboard.getAvailableDataFlavors();
if ( transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor) ) {
copied = (String)transferable.getTransferData(DataFlavor.stringFlavor);
} else {
System.out.println("Could not find a suitable flavor.");
if ( transferable.getTransferDataFlavors().length == 0 ) {
System.out.println("no supported flavors");
}
for ( DataFlavor availableFlav : availableFlavors ) {
System.out.println("availableFlav = " + availableFlav);
}
for ( DataFlavor flavaflav : transferable.getTransferDataFlavors() ) {
System.out.println("transferDataFlavor = " + flavaflav);
}
}
// I am not sure what could cause the below exceptions to happen, but we should just fail the case if they occur.
} catch (IOException e) {
e.printStackTrace();
fail("IOException while fetching copied text.");
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
fail("UnsupportedFlavorException while fetching copied text.");
}
return copied;
Running this code with xvfb is resulting in the following output:
Could not find a suitable flavor.
no supported flavors
And then throws the NullPointerException.
Is there a way to fake a system clipboard that actually works in this headless linux server?
What might be causing the system clipboard running in xvfb to have nothing copied?

Related

IntelliJ Idea how can I set an audio notification when a breakpoint is reached?

With the IntelliJ Idea, when setting a breakpoint that doesn't hit frequently (or not at all), I leave my computer. I'll return ~every 10 minutes to check if the breakpoint has been reached. This process would make use of my time more efficient if I could hear when the breakpoint has been reached. Is this possible?
EDIT:
1) The following works as code, but I need to execute an .mp4 file instead of .app. See the second block of code for that attempt, which doesn't work.
2) Though the code works for .app, how would I set the breakpoint to execute that code when it is reached?
This works as code:
try {
Runtime.getRuntime().exec("/usr/bin/open -a iTunes.app");
} catch (IOException e) {
e.printStackTrace();
}
This doesn't
try {
Runtime.getRuntime().exec("MacintoshHD/Users/myusername/Music/iTunes/iTunes Media/Tones -a 01 Zelda Gets Item Alert Tone.m4a");
} catch (IOException e) {
e.printStackTrace();
}
btw, I did try putting quotes around the path items that had spaces. That didn't work either.
Add this to Evaluate and log:
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File("some.wav"));
clip.open(inputStream);
clip.start();
Thread.sleep(10000);
or execute some application to do it:
try {
Runtime.getRuntime().exec("\"C:\\Program Files (x86)\\Winamp\\winamp.exe\" \"C:\\some.mp4\"");
} catch (IOException e) {
e.printStackTrace();
}
If you are on Windows, you can create a very simple script in powershell, which will making a beeping sound whenever it is ran. (This will run at frequency 500 for 3 seconds).
[console]::beep(500,3000)
Then in the evaluate section of the debugger just add a watch variable that calls the script using powershell:
Runtime.getRuntime().exec("powershell.exe \"C:\\Users\\myusername\\test.ps1\"")

Can Not find static text control when the test is executed on virtual machine

I am using Microsoft Automation UI framework to develop my automation test cases. The problem I faced with is related to interaction with static text control. I am just trying to get the control's text. The test work perfect when I run the test on my local machine. The problem is when I run the test via Test Controler on the (no matter which) Test Agent. The error which appear is that the static control text can not be found.
Theis is the part of my code where I am trying to initialize the control I want to interact with:
private void Init(TreeScope treeScope, params Condition[] properties)
{
try
{
List<Condition> propertiesList = properties.ToList();
propertiesList.Add(Condition.TrueCondition);
bool controlFound = Wait.ForCondition(
() =>
{
try
{
TestControl = Parent.FindFirst(treeScope,
new System.Windows.Automation.AndCondition(propertiesList.ToArray()));
return !TestControl.Current.IsOffscreen;
}
catch
{
return false;
}
});
if (!controlFound)
{
throw new ElementNotAvailableException(DescriptiveName + "Control is NOT found");
}
this.GetItAsUITestControl().WaitForControlReady(Playback.PlaybackSettings.WaitForReadyTimeout);
if (TestControl.Current.IsKeyboardFocusable)
{
TestControl.SetFocus();
}
string controlFullName = this.TestControl.Current.ControlType.ProgrammaticName;
DescriptiveName = "< " + DescriptiveName + " " + controlFullName.Substring(controlFullName.LastIndexOf(".")) + " >";
}
catch (ElementNotAvailableException ex)
{
Report.Error(ex.Message);
}
catch (Exception ex)
{
Report.Error(ex.Message);
}
}
Any ideas?
I am using Microsoft System Center Virtual Machine Manager 2008 R2 for managing my virtual machines (I think all machines are vmware). But from my prespective the problem is not in the virtual machine because all of the tests are executed without any problems on the VM except the one which verify the Static Text Control content. I am 100% sure that the desctop of the VM where the tests are executed is active because I am able to look at it using VMWare Remote Console.
In terms of execution of the tests on the remote machine I am using Test Controlers and Test Agents which comes with Visual Studio.

Automatically close PhantomJs after running script

I want to run PhantomJs scripts from my program, but since the scripts may not be written by me, I need to make sure PhantomJs exits after the execution are either completed or fails for any reason (e.g., invalid syntax, timeout, etc). So far, All I've read says you must always include the instruction phantom.exit() for PhantomJs to exit. Is there any way to automatically close PhantomJs after it executes a given script?
Thanks.
Create a file run-javascript.js:
var system = require('system');
try {
for (var i=1; i<system.args.length; i++) {
var scriptFileName = system.args[i];
console.log("Running " + scriptFileName + " ...");
require(scriptFileName);
}
}
catch(error) {
console.log(error);
console.log(error.stack);
}
finally {
phantom.exit();
}
Then to run your file myscript.js:
phantomjs run-javascript.js ./myscript.js
You have to include an explicit path for the myscript.js, i.e. ./myscript.js, otherwise phantomjs will look for the script as a module.
There are three execution scenarios that are handled here:
Successful execution, in which case phantom.exit() is called in the finally clause.
Error in the script being run, in which case the require function prints a stacktrace and returns (without throwing any error to the calling code).
Error running the script (e.g. it doesn't exist), in which case the catch clause prints out the stacktrace and phantom.exit() is called in the finally clause.

Why JDK's JConsole seek virtual machines using both jvmstat and attach api?

I'm writing some JVM instance related application and looking at open source to see how it's solve some problems. The JConsole from JDK7 collects running VMs in two ways (look at source licensed by GPL2 in jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java). The first is jvmstat way, code like this:
private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
MonitoredHost host;
Set vms;
try {
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
vms = host.activeVms();
} catch (java.net.URISyntaxException sx) {
throw new InternalError(sx.getMessage());
} catch (MonitorException mx) {
throw new InternalError(mx.getMessage());
}
for (Object vmid: vms) {
if (vmid instanceof Integer) {
int pid = ((Integer) vmid).intValue();
String name = vmid.toString(); // default to pid if name not available
boolean attachable = false;
String address = null;
try {
MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));
// use the command line as the display name
name = MonitoredVmUtil.commandLine(mvm);
attachable = MonitoredVmUtil.isAttachable(mvm);
address = ConnectorAddressLink.importFrom(pid);
mvm.detach();
} catch (Exception x) {
// ignore
}
map.put((Integer) vmid,
new LocalVirtualMachine(pid, name, attachable, address));
}
}
}
Second is attach way, and looks like this:
private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vms) {
try {
Integer vmid = Integer.valueOf(vmd.id());
if (!map.containsKey(vmid)) {
boolean attachable = false;
String address = null;
try {
VirtualMachine vm = VirtualMachine.attach(vmd);
attachable = true;
Properties agentProps = vm.getAgentProperties();
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
vm.detach();
} catch (AttachNotSupportedException x) {
// not attachable
} catch (IOException x) {
// ignore
}
map.put(vmid, new LocalVirtualMachine(vmid.intValue(),
vmd.displayName(),
attachable,
address));
}
} catch (NumberFormatException e) {
// do not support vmid different than pid
}
}
}
My question: why it uses two different tools for retrieving virtual machines list? I know that through attach api you can list VMs running by this same JRE only, but jvmstat can give you list of all VMs running with any JRE versions. I have tested JRE/JDK 7 32 and 64-bit only because theys and newer are my target, sadly on windows only. Is not suffiecient to use jvmstat only? Is there any case when some VM is visible by attach api, but jvmstat can't see it?
Usually, for finding all jvm process, attach api is equal to jvmstat. But in some customized circumstances, it's diffrent. And the diffrent is com.sun.tools.attach.spi.AttachProvider.
e.g. in Windows platform, jvmstat finds java process by listing all files in the directory %TEMP%/hsperfdata_caoxudong(In linux, it is /tmp/hsperfdata_caoxudong). And attach api finds java processes by AttachProvider instance. jdk provides a default an AttachProvider implementation, which depends on your OS platform. In Windows Platform, the implementation is sun.tools.attach.WindowsAttachProvider. In its listVirtualMachines method, if isTempPathSecure method return false, it will iterate all processes, and find all processes, which loaded library "jvm.dll". You can install your own AttachProvider implementation to find java processes with your own ways, and the result may be diffrent with jvmstat.
The installation of AttachProvider is here.

Eclipse plugin: about the function --println(String) in org.eclipse.ui.console.MessageConsoleStream

Recently I am doing a eclipse plugin project with eclipse_RCP. But I encountered some issues with eclipse UI when I wanted to print a large number of messages in the console of plugin.
The messages are from a complex process which could be considered as a factory producing messages all the time and never stop (until the client stop the process of course).
When I printed the message before (the message is short), I just needed to call the function -org.eclipse.ui.console.MessageConsoleStream.println().
BUT this time ,when I tried like before at first , the runtime-EclipseApplication (launch the debug mode) stopped responding and then tell me out of memory.
It seems like that the eclipse will read all the messages in the memory and THEN print them to the console one time .So when the number of message is large ,it will out of memory.
My issue is what can I do if I want to print the message line by line in the console ?
My description may be not accurate. Below is the java code:
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
try {
while ((line = in.readLine()) != null) {
//it is correct when print in the main console
System.out.println(line);
//when print in plugin console .it is out of memory
//this is the function
//org.eclipse.ui.console.MessageConsoleStream.println()
println(line);
}
in.close();
this.flush();
this.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then I try to write to a file at first and let the MessageConsoleStream read from the file every 1000 messages,but it looks like the same .
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
char []tem = new char[1024];
int i = 0 ;
try {
File temp = File.createTempFile("temp", ".tep",new File("E:/"));
FileWriter out = new FileWriter(temp);
MessageConsoleStream mcs = null;
while((line = in.readLine())!=null){
if(i<=1000){
System.out.println(line);
out.write(line+"\n", 0, line.length()+1);
i++;
}
else{
i=0 ;
out.flush();
out.close();
FileReader fr=new FileReader(temp);
mcs = CConsole.getMessageStream("consoleName", "file name");
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
fr.close();
out = new FileWriter(temp,false);
}
}
if(i!= 0){
mcs = CConsole.getMessageStream("consoleName", "file name");
out.flush();
out.close();
FileReader fr=new FileReader(temp);
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
}
in.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
All the ways above will make the eclipse out of memory when the number of messages more than 600,000 (then I stop the process ,otherwise it will out of memory).
It looks like the ecplipse wants to print all of them one time but not line by line.So it reads and reads again until out of memory.
BTW,I find a note in the org.eclipse.ui.console.MessageConsoleMessage.java——
Clients should avoid writing large amounts of output to this stream
in the UI thread. The console needs to process the output in the UI
thread and if the client hogs the UI thread writing output to the
console, the console will not be able to process the output.
That is not the real reason ,isn't it ?
I also notice that both the cdt and jdt are ok when printing a large number of message .How did they do ?
THANKS!
You have to use the flush() method every so often to write the MessageConsoleStream out to the console.
The flush() method is part of the IOConsoleOutputStream class, in the org.eclipse.ui.console package. The flush() method is not well documented, so I can see how you might have missed it.