addEventListener on AppNavItem - event-handling

I am using latest version of Vaadin.
Intended: want to catch an event if AppNavItem (with child elements) is clicked (expanded, toggled).
Code:
#JsModule("#vaadin-component-factory/vcf-nav")
#Tag("vcf-nav-item")
public class AppNavItem extends Component {
public AppNavItem(String label) {
setLabel(label);
}
public AppNavItem setExpanded(boolean value) {
if (value) {
getElement().setAttribute("expanded", "");
} else {
getElement().removeAttribute("expanded");
}
return this;
}
public AppNavItem setIcon(Component icon) {
icon.getElement().setAttribute("slot", "prefix");
int iconElementIndex = getIconElementIndex();
if (iconElementIndex != -1) {
getElement().setChild(iconElementIndex, icon.getElement());
} else {
getElement().appendChild(icon.getElement());
}
return this;
}
}
AppNavItem myItem = new AppNavItem("Project");
myItem.addAttachListener(e -> {
System.out.println(e.toString()); // works on page load as expected !
});
//projectParent.onEnabledStateChanged(false); // does not work
//projectParent.onEnabledStateChanged(true); // does not work
myItem.getElement().addEventListener("onchange", e -> {
System.out.println(e.getType()); // does not work
});
myItem.getElement().addPropertyChangeListener("expanded","onchange", e -> {
System.out.println(e.getPropertyName()); // does not work
});
myItem.getElement().addEventListener("onchange", e -> {
System.out.println(e.getType());
});
myItem.getElement().addPropertyChangeListener("expanded","onchange", e -> {
System.out.println(e.getPropertyName()); // does not work
});
myItem.getElement().addPropertyChangeListener("expanded", e -> {
System.out.println(e.getPropertyName()); // does not work
});
myItem.addItem(...);
I tried several eventTypes like: click, onclick, change, onchange, ontoggle, ...
Unfortunately, almost nothing works, see comment.
What am I doing wrong ?
I expect to catch an event

Related

jasmine: Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.. When i am trying get a non present element

When I am trying to check presence of not presented element/ button. I am getting:
Jasmine timeout exception
My code like
getName(): any {
let name = element(by.id("xxxxxx"));
return name.isPresent().then((ispresent) => {
if (ispresent) {
return name.getText();
} else {
return '';
}
})
}
I am trying to access that method expect(method).toequal('');
It should run, because if not present i am expecting empty string but i am getting Jasmine timeout.. I didn't added any waits any where.
isPresent()
From the GitHub repo, ElementFinder.isPresent
isPresent(): wdpromise.Promise<boolean> {
return this.count().then((count) => {
return count > 0;
});
}
isPresent checks for a count, but does not catch if there is an error. If the count throws, we should probably return 0. Getting a text for an element that does not exist should also have throw a promise rejection.
Note: It might be better to change your method to async / await (optional).
async getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
try {
return name.getText();
} catch (e) {
return '';
}
}
Or not async / await
getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
return name.getText().catch(e) {
return '';
}
}
Try the below one
async getName() {
let name = element(by.id("xxxxxx"));
let value: string = '';
await name.ispresent().then((ispresent) => {
if (ispresent) {
value=name.getText();
}
});
return value;
}
Hope it helps you

syntax for verifying if the element is present for protractor serenity

What is the syntax for checking if the element is present? I need to check if the element is present in order to go further in my test. If the element is not present i want to perform some other action.
This is what I am trying but the syntax does not work in serenity:
import {Click, PerformsTasks, Task, step, Wait, Is} from "serenity-js/lib/screenplay-protractor";
import {ProductDetailPageMap} from "../interactions/element-mappings/ProductDetailPageMap";
import { Interaction, UsesAbilities, AnswersQuestions } from "serenity-js/lib/screenplay-protractor";
import { Target, Attribute, BrowseTheWeb } from "serenity-js/lib/screenplay-protractor";
import { ElementArrayFinder, ElementFinder, $$, browser } from "protractor";
export class AddItemToWishlist implements Task {
static called(): AddItemToWishlist {
return new AddItemToWishlist();
}
private parseSizeList(elements: ElementArrayFinder): any {
if (elements.isPresent()) {
Click.on(ProductDetailPageMap.addToWishlist)
} else {
Click.on(ProductDetailPageMap.removeFromWishlist)
browser.sleep(2000);
Click.on(ProductDetailPageMap.addToWishlist)
}
}
#step('{0} Add Item to the Wishlist')
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
//return
);
}
}
I am not sure what to add in the return though??
var logoutButton = element("//button[#type='submit']/span[.='Add to wishlist']");
logoutButton.isPresent().then(function (result) {
if (result) {
// Element IS PRESENT...DO SOMETHING
} else {
// Element IS NOT PRESENT...DO SOMETHING
};
});

How to sequentially execute a "Completable" followed by "Single"?

I have two reactive methods in "Layer A" that's exposed to the app:
LAYER A - publicly accessible methods to the rest of the app
public Single<ResponseData> postMyData(ReqData data, Long id) {
if (!isUserLoggedIn()) return postLogin().andThen(postData(data, id));
return postData(data, id);
}
public Completable postLogin() {
Account account = getAccountData();
ReqLoginData loginData = new ReqLoginData(account.email, account.pass, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET);
Single<ResponseLogin> singlePostLogin = postLogin(loginData);
return Completable.create(subscriber -> singlePostLogin.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(loginResponse -> {
// Success
storeAccessToken(loginResponse);// *** this will recreate apiClient with new access token
if (!subscriber.isDisposed()) subscriber.onComplete();
}, throwable -> { if (!subscriber.isDisposed()) subscriber.onError(throwable);}
));
}
LAYER B - only accessible by Layer A
public Single<ResponseLogin> postLogin(ReqLoginData loginData) {
Log.d(TAG, "using apiClient "+apiClient.toString());
Single<Response<ResponseLogin>> postLogin = apiClient.postLogin(loginData);
return Single.create(subscriber -> postLogin.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
}));
}
public Single<ResponseData> postData(ReqData data, Long id) {
Log.d(TAG, "using apiClient "+apiClient.toString());
Single<Response<ResponseData>> postData = apiClient.postData(id, data);
return Single.create(subscriber -> postData.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
}));
}
LAYER C - API Interface
#Headers({"Content-Type: application/json"})
#POST(Constants.API_PREFIX + "/auth/token/")
Single<Response<ResponseLogin>> postLogin(#Body ReqLoginData reqLoginData);
#Headers({"Content-Type: application/json"})
#POST(Constants.API_PREFIX + "/data/{id}/")
Single<Response<ResponseData>> postData(#Path("id") Long id, #Body ReqData reqData);
A huge challenge for me at the moment is to make sure the user is logged-in before attempting to POST data. So, using postLogin().andThen(postData(data, id)) made sense to me :
At the time of my late-night development, it seemed that both methods postLogin() and postData() are called in parallel - with postLogin() first.
How can I make postMyData() execute postLogin() first, wait for success or failure, followed by postData() on success ?
Note: postLogin() will update apiClient with the new token inside storeAccessToken(). I now see that postData() doesn't use a reference to the new apiClient. It's important that postData() will use the new apiClient that's instantiated within storeAccessToken()
Sorry for the newbie question :-(
it turned out that Completable.andThen(Single) works very well to serialize code execution. Unfortunately, I didn't (half asleep) realize that only code within the create() method was actually scheduled.
my code below answers the problem I had (these are both in LAYER-B):
public Single<ResponseLogin> postLogin(ReqLoginData loginData) {
return Single.create(subscriber -> {
Log.d(TAG, "using apiClient "+apiClient.toString());
apiClient.postLogin(loginData)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.isSuccessful() && response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
});
});
}
public Single<ResponseData> postData(ReqData data, Long id) {
return Single.create(subscriber -> {
Log.d(TAG, "using apiClient "+apiClient.toString());
apiClient.postData(id, data)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
});
});
}

Why TextDocumentContentProvider dont call provideTextDocumentContent on update when query params changes?

as title says, when i wanna update TextDocumentContentProvider with different query params by calling update method provideTextDocumentContent is not called...
only way i managed to get it working was with same URI as in calling
vscode.commands.executeCommand('vscode.previewHtml', URI, 2, 'Storybook');
relevant part of code:
// calculates uri based on editor state - depends on actual caret position
// all uris will start with 'storybook://preview'
function getPreviewUri(editor: vscode.TextEditor): vscode.Uri;
// transforms uri, so web server will understand
// ex: 'storybook://preview?name=fred' -> 'http://localhost:12345/preview/fred?full=1'
function transformUri(uri: vscode.Uri): vscode.Uri;
class StorybookContentProvider implements vscode.TextDocumentContentProvider
{
provideTextDocumentContent(uri: vscode.Uri): string {
var httpUri = transformUri(uri);
return `<iframe src="${httpUri}" />`;
}
onDidChange = new vscode.EventEmitter<vscode.Uri>();
update(uri: vscode.Uri) {
this.onDidChange(uri);
}
}
export function activate(context: vscode.ExtensionContext)
{
vscode.workspace.onDidChangeTextDocument(
(e: vscode.TextDocumentChangeEvent) => {
if (e.document === vscode.window.activeTextEditor.document) {
const previewUri = getPreviewUri(vscode.window.activeTextEditor);
provider.update(previewUri);
}
}
);
vscode.window.onDidChangeTextEditorSelection(
(e: vscode.TextEditorSelectionChangeEvent) => {
if (e.textEditor === vscode.window.activeTextEditor) {
const previewUri = getPreviewUri(vscode.window.activeTextEditor);
provider.update(previewUri);
}
}
);
const provider = new StorybookContentProvider();
context.subscriptions.push(
vscode.commands.registerCommand('extension.showStorybook', () => {
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.parse('storybook://preview'), 2, 'Storybook')
}),
vscode.workspace.registerTextDocumentContentProvider('storybook', provider)
);
}

hash format error! using routing

I have developed an OpenUI5 app ant it works fine!
But every time that I invoke the routing I have this message:
2015-07-15 16:15:45 hash format error! The current Hash: /line/01 -
log
error
onHashChange
detectHashChange
jQuery.event.dispatch
jQuery.event.add.elemData.handle
It is not a blocking problem but it is annoying because it dirty and fills thi debug console..!
To call the router I write:
this.router = sap.ui.core.UIComponent.getRouterFor(this);
this.router.navTo("activities", {
"id_line": '01'
});
and this is the routing file:
routes: [
...
{
pattern: "line/{id_line}",
name: "activities",
target: ["master_search", "detail_activities"]
},
...
],
targets: {
master_search: {
viewName: "UniversalMenu",
viewLevel: 1,
controlAggregation: "masterPages"
}
,
detail_activities: {
viewName: "DetailActivity",
viewLevel: 4
}
...
}
Edit: this is a snippet where I use jQuery.sap.history
jQuery.sap.require("jquery.sap.history");
jQuery.sap.require("sap.m.InstanceManager");
sap.ui.controller("ui5bp.view.App", {
getDefaultPage : function () {
return "Menu";
},
onInit : function () {
var historyDefaultHandler = function (navType) {
if (navType === jQuery.sap.history.NavType.Back) {
//this.navBack(this.getDefaultPage());
} else {
this.navTo(this.getDefaultPage(), null, false);
}
};
var historyPageHandler = function (params, navType) {
if (!params || !params.id) {
jQuery.sap.log.error("invalid parameter: " + params);
} else {
if (navType === jQuery.sap.history.NavType.Back) {
this.navBack(params.id);
} else {
this.navTo(params.id, params.data, false);
}
}
};
jQuery.sap.history({
routes: [{
// This handler is executed when you navigate back to the history state on the path "page"
path : "page",
handler : jQuery.proxy(historyPageHandler, this)
}],
// The default handler is executed when you navigate back to the history state with an empty hash
defaultHandler: jQuery.proxy(historyDefaultHandler, this)
});
// subscribe to event bus
var bus = sap.ui.getCore().getEventBus();
bus.subscribe("nav", "to", this.navHandler, this);
bus.subscribe("nav", "back", this.navHandler, this);
bus.subscribe("nav", "virtual", this.navHandler, this);
},
navHandler: function (channelId, eventId, data) {
if (eventId === "to") {
this.navTo(data.id, data.data, true);
} else if (eventId === "back") {
//**************************************************
// if(data && data.id){
// this.navBack(data.id);
// } else {
// jQuery.sap.history.back();
// }
var app = this.getView().app;
if(data.type==="master"){
app.backMaster();
}else if(data.type==="detail"){
app.backDetail();
}else{alert("back to master o detail?");};
//**************************************************
} else if (eventId === "virtual") {
jQuery.sap.history.addVirtualHistory();
} else {
jQuery.sap.log.error("'nav' event cannot be processed. There's no handler registered for event with id: " + eventId);
}
},
navTo : function (id, data, writeHistory) {
if (id === undefined) {
// invalid parameter
jQuery.sap.log.error("navTo failed due to missing id");
} else {
var app = this.getView().app;
// navigate in the app control
app.to(id, "slide", data);
}
},
/*
navBack : function (id) {
if (!id) {
// invalid parameter
jQuery.sap.log.error("navBack - parameters id must be given");
} else {
// close open popovers
if (sap.m.InstanceManager.hasOpenPopover()) {
sap.m.InstanceManager.closeAllPopovers();
}
// close open dialogs
if (sap.m.InstanceManager.hasOpenDialog()) {
sap.m.InstanceManager.closeAllDialogs();
jQuery.sap.log.info("navBack - closed dialog(s)");
}
// ... and navigate back
var app = this.getView().app;
var currentId = (app.getCurrentPage()) ? app.getCurrentPage().getId() : null;
if (currentId !== id) {
app.backToPage(id);
jQuery.sap.log.info("navBack - back to page: " + id);
}
}
}
*/
});
In Component.js I had 2 rows where I set up custom myNavBack and myNavToWithoutHash functions:
// 3a. monkey patch the router
var oRouter = this.getRouter();
oRouter.myNavBack = ui5bp.MyRouter.myNavBack; //to comment
oRouter.myNavToWithoutHash = ui5bp.MyRouter.myNavToWithoutHash; //to comment
I have started from an example of app skeleton for my app and then I have implemented the routing with the logic suggested from the framework.
This coexistence of two different methods to navigate produced the error in console. Tahnkyou #TimGerlach
After the comment of the two rows errors have vanished.