How to check if a form is fully loaded? - microsoft-ui-automation

I have forms that contain controls in my application under test. These controls load data in their own threads.
I would like to add a block until the form is fully loaded.
How is this done?

I think the cleanest way to do that is to listen to AsyncContentLoadedEvent.
An other way, which assumes you know which components needs to be loaded, is to search the UI Automation Tree for the AutomationElement(s) directly (FindAll, FindFirst, TreeWalker).
If all AElements are available it means it's loaded. You could consider the childCount or various AutomationElementProperties to verify that. Of course several Patterns (e.g. ValuePattern) could be additionally used to verify the state of the AElements.
Alternativly to AsyncContentLoadedEvent, you could check out if your application uses some kind of UI Element for showing the current status of the loading process (HelpTextProperty, Icon, Label, etc..).
In such case I would simple query this certain AElement for it's current value/name/.. (or also color (not directly supported by UI Automation and requires some workaround)). and wait until it has the required state

Related

Cocoa invoke Service, do not overwrite Pasteboard

I have created a Service in Cocoa which grabs the selected Text and sends the result back to my Main App, so i can handle it there ( Couldn't find any other way to get current selection), now that the Service works and appears in the Service Menu, i tried to invoke the Service from my parent App to get current selection, after some goggling around i found this snippet:
NSPasteboard *pboard = [NSPasteboard pasteboardWithUniqueName];
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
NSPerformService(#"PCB", pboard);
This one works as far as it triggers my Service, the Problem here is it redefines the NSPasteboard, so my service doesn't get the selected text, but a NIL Value Pasteboard which is blank, how can i prevent this?
And does someone know how to convert a .service bundle into an .app bundle that performs itself and sends the data and kills itself after finish?
thx for help
You want to get the text that is selected in another application, right? Probably in the front application, while your app is in the background.
For this to work, you'd have to have the Service be invoked by the front application. If you invoke it from your app in the background, it can't access the front app's text field that contains the selected text. Instead, it'll try to find a text field in your own app's responder chain (I believe – someone correct me if I'm wrong on this detail).
But for your code to run in the app's process, you'll have to inject it somehow, which is - out of security concerns - mostly prohibited by OS X, and especially with sandboxed apps.
There are ways to accomplish code injection, one that 1Password and other popular tools use it through an osax extension. But that's an entirely different topic.
Once you have your code running inside the other app's process, you should be able to copy the selected text (provided it's a Cocoa app) with [NSTextView writeSelectionToPasteboard:types:]. I haven't tested this myself, though, so this is just an assumption.

Stopping Ember.js Controller

My question is very basic on one hand but on the other hand the general situation is more complex, plus I cannot really get any working sample.
I'm developing/maintaing a web-application which is currently in transition from GWT code base into Ember.js.
Most of the newer code already relies on Ember.js and I think it's really awesome.
The problem is we cannot use Ember Router as all the request are being handled by the GWT.
In order to enabled the application run in this unusual configuration we have special JavaScript files that create our Ember main objects (Controllers & Models) for us.
As you can imagine navigation between tabs is cumbersome and is handled by GWT who creates Ember objects when needed. We are in transit toward a brave new world Ember Router and all.
But in the meantime, this is the problem I'm facing right now.
The user clicks a link which opens a page that contains some Ember based table.
The data is retrieved form the server using some Ajax code. Upon success it spawns a forEach loop which tries to pushObject all the received date into our Ember based components.
My problem happens when the user quickly switches between tabs. In this case the first list of object has not finished rendering yet and suddenly there's a new set of objects to handle. This causes Ember to throw errors like:
"Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM. "
and
"Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist."
Is it possible to prevent the loop from trying to render?
I've tried checking if the controller in question is already inDOM and it is, is there a way to notify Ember this object is no longer valid?
Sorry for a lengthy question and lack of running sample.
I'd probably modify the switch tab code to only execute afterRender has completed, that way you aren't mucking with ember objects while they are being used.
Ember.run.scheduleOnce('afterRender', this, function(){
// call GWT switch tab routine
});
Thank you Daniel and Márcio Rodrigues Correa Júnior. eventually what I did is to add a patch that would check the current context of the application (in my case the currently selected tab). If upon receiving the AJAX response the application is in the correct context (meaning the user haven't change the tab) go on. Otherwise just ignore the response and do not try to render it.
Now it seems to be working

How can I restore the synchronization between the auto-create forms list and the DPR initialization code?

I have a D2006 app in which the DPR file has had numerous edits (yes, I know - you shouldn't mess with the DPR file) to accommodate such things as a splash screen, preventing a second instance of the app being started, handling of command line options that need to be processed before any forms are created, etc.
One day, I noticed that the auto-create forms list in the project options is empty - but the DPR file still has the code in there to create some of the forms.
If I try to restore all the forms that should be auto-created from the dialog, it complains Error - Call to Application->CreateForm is missing or incorrect and doesn't do anything.
How can I restore this connection - apart from rebuilding the DPR from scratch?
is it safe to manually add the CreateForm calls?
are there any documented rules as to what you can do in the DPR file?
I have a suspicion that try..except and if..else clauses in the DPR upset Delphi. Will moving as many functions as possible to a separate unit and calling them be helpful?
I haven't really seen any documented rules as to what you can do in the DPR file, because I guess there are no strict rules.
The problem begins when you create a "Forms" application. (No problems with console or non-GUI applications I've noticed).
The IDE will automatically change the DPR any time you add a new Form or a DataModule to it, by assuming you want to auto-create them.
This can mess up your DPR, if it has a lot of code/compiler-directives/if-blocks/try-catch blocks etc...
So I'll tell you what my rules are, and in a short line:
Keep it as simple as you can.
My DPR contains only a call to some init code and auto creates the main form only:
MyAppInit; // in AppInit unit
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
However in the uses section I add (or keep what the IDE added) all the forms my application uses (and also application related units) - this is useful when I want to view->forms or view-units.
In-fact when I add a new form to the application, the first thing I do is go the DPR and remove the line:
Application.CreateForm(TMyNewForm, MyNewForm);
NOTE (EDIT): The IDE can be configured to NOT auto create forms (No Application.CreateForm entry will be created in the DPR). In older version of Delphi this option is under: Tools/Environment Options/Preferences -> Auto create forms. In newer versions: Tools/Options/VCL Designer/Module creation options -> Auto create forms & data modules.
At run-time, I create all my forms dynamically when I need them, and destroy them when they no longer needed. DataModules/Splash (etc...) are created on the MainForm.OnCreate event.
This method has worked for me nicely for the past few years maintaining a large scale DB application. This will probably not cover all cases, but it worked fine for my needs.
P.S: "Is it safe to manually add the CreateForm calls" - Yes. But think twice if you really need them to be auto-create by the application.
IMHO You don't really need that AutoCreate forms from Delphi, but maybe in the casual test project.
And the dpr is just another source code file, where you're meant to write code to make things happen (or prevent it to happen), so don't worry if you lost that sincronization, which IMHO is buggy if can't read your pascal code to work properly.
If you still want to create some forms from the DPR, add the Application.CreateForm or TMyForm.Create calls manually to the file, AFAIK there's no rules against doing it that way.
Since Delphi owns the .DPR, I put my startup logic into a separate unit for each project.
That works really well, only very few entries need to be in the .DPR.
Since that unit controls the Application.CreateForm logic too, the IDE has an empty list for that: I'm fine with that.
The only things left in the .DPR are:
the big uses that indicates which modules are part of your project
a call to Main in the startup logic unit

How do you set up an Optimizely test for a single-page app?

I have a single-page web app that presents a multi-step photo management "wizard", split up across several discrete steps (photo upload, styling, annotation, publishing) via a tab strip. On switching steps I set the URL hash to #publishing-step (or whichever step was activated).
How do I set up Optimizely tests to run on the various discrete steps of the wizard?
The browser never leaves the page, so it only gets a single window.load event. Its DOM isn't getting scrapped or regenerated, but just switches what page elements are visible at any one time via display: none or block, so the part I am trying to figure out is really mostly about in what way I go about the Optimizely test setup itself - it's fine (and likely necessary) if all edits get applied at once.
This thing unfortunately has to work in IE9, so I can't use history.pushState to get pretty discrete urls for each step.
There's actually several ways you could go about doing this, and which option you choose will largely depend on what's easiest for you AND how you plan to analyze the data.
If you want to use Optimizely's analytics dashboard:
I would recommend creating one experiment which will activate a bunch of other experiments at different times. The activation experiment will be targeted to everyone and run immediately when they get to your wizard. The other experiments will be set up with manual activation and triggered by this experiment.
The activation experiment would have code like:
window.optimizely = window.optimizely || [];
function hashChanged() {
if(location.hash === 'publishing-step') {
window.optimizely.push(['activate', 0000000000]);
}
if(location.hash === 'checkout-step') {
window.optimizely.push(['activate', 1111111111]);
}
}
window.addEventListener('hashchange', hashChanged, false);
Or you could call window.optimizely.push(['activate', xxxxxxxxx]); directly from your site's code instead of creating an activation experiment and listening for hashchange.
If you want to use a 3rd party analytics tool like Google Analytics:
You could do this all in one experiment with code similar to above, but in each "if" section instead of activating an experiment, you could run your variation code that makes changes to the wizard and sends special tracking information to your analytics sweet for later reporting. You'll have to do your own statistical significance calculation for this method (as Optimizely's data won't be "clean"), but this method actually works out better usually if properly configured.
Alternatively you could use the method outlined above but still try to use the Optimizely analytics dashboard by creating custom events on your experiment and sending data to them using calls like window.optimizely.push(["trackEvent", "eventName"]);
This article may also be helpful to you.
You'll probably need to do this yourself, using Optimizely's JS API to trigger actions on their end and tell it what your users did: https://www.optimizely.com/docs/api

Eclipse RCP fireSelectionChanged from Non-SWT client

I have the following problem:
I have a framework in which arbitrary clients can run. Imagine you have a non-swt/non-swing client and you want to invoke a fireselectionchanged event to the Workbench. Is that possible somehow.
Once again. I am not able to get the edior/viewer or something else in my plugin!
Thank you very much
At any given time there can be only one selection provider per workbench window/page and it's the one provided by active workbench part. Hence, it's only possible to provide selection and notify selection change from a view or an editor.
While it is possible to access the selection provider of current active part and set selection to it...
workbenchWindow.getActivePage().getActivePart().getSite().
getSelectionProvider().setSelection(ISelection);
...it's not guaranteed that (1) there is an active part at the time and that (2) the selection provider of the active part supports the type of selection that you want to provide.