I'm trying to write a deploybot with nodejs, but when trying to navigate to the environments page it fails to find this button.
Here is the snippet of code:
//wait until element with unique id containing the environments button is there
await page.waitForSelector('#formatstring_widget_formatstring_14');
//check if the element actually exists, so that i can log that.
const envElement = await page.$('#formatstring_widget_formatstring_14');
if (envElement != null) {
console.log('env element exists');
} else {
console.log('no env element found');
}
const link = await page.evaluate((env)=> {
env.innerHTML;
}, envElement);
console.log('env= '+link);
If I run this, I get a log of:
'Env element exists'
'Env = undefined'
which means the element exists, but there is no innerHTML? but when I inspect the source code from the page I'm accessing, the
id=#formatstring_widget_formatstring_14 does have inner html
How is this possible?
Here is the source code
<div data-mendix-id="51_37_138" class="mx-name-formatString1 mx-link submenu-item page-nav-9" tabindex="0" id="formatstring_widget_formatstring_14" focusindex="0" widgetid="formatstring_widget_formatstring_14" style="">
<div class="formatstring ">
<a href="https://cloud.home.mendix.com/link/deploy/d22310d5-a10f-437b-93d7-c0ceab21d0c6" class="">
Environments</a>
</div></div>
It might be far easier to use the Deploy API from Mendix to automate deployment. See the API here: https://docs.mendix.com/apidocs-mxsdk/apidocs/deploy-api
Regards,
Ronald
Related
Note, this is related to my previous question here: https://stackoverflow.com/a/73043433/4190664
I am looking to further assert somethings within the DOM when I click the 'Print' button.
From troubleshooting I am seeing the following:
the pdfjs page has a #printContainer that is an empty div
when you click the Print button, it begins creating divs with the class .printedPage to represent each page of the document
within each .printedPage div is an img element with src="blob:https://mozilla.github.io/**"
Example when the print dialog is open:
<div id="printContainer">
<div class="printedPage"><img src="blob:https://mozilla.github.io/5afcff4c-aa36-4118-b4b8-011cdce6a9bc"></div>
<div class="printedPage"><img src="blob:https://mozilla.github.io/30cd3036-2d81-4b82-af9a-0f2e9c834b69"></div>
<div class="printedPage"><img src="blob:https://mozilla.github.io/047e8762-3fae-44d1-a5a0-56ea576de93e"></div>
</div>
I already am testing the following:
let requestCount = 0;
page.on('request', request => {
if(request.url().includes('blob:https://mozilla.github.io/pdf.js/web/viewer.html')) {
expect(page.locator(`.printedPage img >> nth=${requestCount}`)).toHaveAttribute('src', /blob:https:\/\/mozilla.github.io/);
requestCount++;
}
});
await printBtn.click();
await expect.poll(() => requestCount).toBe(3);
What would be the best way to assert that each .printedPage > 'img' src contains the blob information as well?
Playwright (and javascript in general) is not a strong language so I am definitely struggling on this one 😬
Any syntactical help is appreciated
You can do something like this. You can add this before the value of requestCount increments.
await expect(
page.locator(`.printedPage img >> nth=${requestCount}`)
).toHaveAttribute('src', /blob:https:\/\/mozilla.github.io/)
I tried global event listeners pane in Chrome DevTools, I tried to put a debugger; inside document/window.addEventListener("unload", ...) and it is not working.
I tried to step over the statements in the file main.ts and nothing is breaking the code in there when I click on a link that should open another page than the one it is opening. I checked its HTML attributes and the correct URL is set in its href attribute. The link has a single class which is not used to open another page in the page's code as far as I know.
I also searched for all the places in my code where the (window.)location is changed.
I also updated npm packages using npm update.
I use KnockOut.js and I have this static HTML for the links that go to wrong pages:
<ul class="main-nav" data-bind="foreach: mainMenuItems">
<li>
<a data-bind="attr: { href: url, title: text }, text: text, css: { active: $data == $root.activeMenuItem() }"></a>
<div class="bg"></div>
</li>
</ul>
And this is a part of the TypeScript code (sorry for the ugly code, it is WIP):
let vm = new PageViewModel(null, "home", () => {
sammyApp = $.sammy(function () {
// big article URLs w/ date and slug
this.get(/\/(.+)\/(.+)\/(.+)\/(.+)\/(.*)[\/]?/, function() {
vm.language("ro");
vm.isShowingPage(false);
vm.isShowingHomePage(false);
let slug : string = this.params['splat'][3];
vm.slug(slug);
console.log('logging', { language: vm.language(), slug: vm.slug() });
vm.fetch();
vm.isShowingContactPage(false);
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// any other page
this.get(/\/ro\/(.+)\//, function () {
console.log('pseudo-navigating to /ro/etc.');
vm.language("ro");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
this.get(/\/en\/(.+)\//, function () {
console.log('pseudo-navigating to /en/etc.');
vm.language("en");
vm.isShowingPage(true);
vm.isShowingHomePage(false);
let slug : string = this.params["splat"][0];
//slug = slug.substr(0, slug.length - 1);
if (slug !== 'contact') { // this page is in the default HTML, just hidden
vm.slug(slug);
vm.fetch();
vm.isShowingContactPage(false);
} else {
vm.isShowingContactPage(true);
, () => {
uuuuucons
}9 function
window.scrollTo(0, 0);
}
vm.activeMenuItem(vm.getMenuItemBySlug(slug));
});
// the home page
this.get("/", function () {
console.log(`pseudo-navigating to /${vm.language()}/home`);
sammyApp.setLocation(`/${vm.language()}/home`);
});
});
sammyApp.run();
});
I have this code that catches the click event:
$("a").on("click", () => {
debugger;
});
But after this finding I do not know what I can do to find the source of the problem.
When the click is catched by the 3 LOCs above, I get this:
What could be the issue?
Thank you.
Update 1
After seeing these questions and their answers (the only thing I did not try was using an iframe):
How can I find the place in my code or page where the location is set?
Breakpoint right before page refresh?
Break javascript before an inline javascript redirect in Chrome
If I have a page for which I check the beforeunload and unload event checkboxes in the Event Listener Breakpoints pane in Chrome DevTools' tab Sources, and I click on a link which should not reload the page but it does, and the two breakpoints (beforeunload and unload) are not triggered in this process, what should I do next?
Is this a known bug? If so, can someone give me an URL?
Thank you.
On the template list of users, I have a column to show the identity image (stored on database) of each user.
On the template file, I have:
<td>
<img src="{{emptyStr.concat(user.pathImage.substr(user.pathImage.indexOf('/assets')))}}" style="max-width:30px"/>
<br/>
{{user.nameImage}}
<br/>
{{emptyStr.concat(user.pathImage.substr(user.pathImage.indexOf('/assets')))}}
</td>
On the component file, emptyStr = "..";
As displayed bellow:
The name and the url of the image are displayed correctly.
However, the image cannot be loaded.
On firefox, there's no error.
However on chrome, I got this error:
Also, I got:
That means that this image doesn't exists on file upload, but no, that exists as displayed by this screenshot.
I think there's a problem of synchronization, because after made some changes on sublime tool, the console ng server will update and both 2 images are shown.
Have you please any idea about solving that issue ?.
Big thanks.
Try this way:
On the template .html:
< img src="{{showImage(user.id)}}" alt="{{showImage(user.id)}}" style="max-width:30px"/>
On the component .ts:
strIntoObjExp: String[] = [];
specialUser: User;
user: User;
showImage(id: number) : String
{
var requesta = new XMLHttpRequest();
requesta.open('GET', 'http://localhost:6227/api/auth/getallfiles', false);
requesta.send(null);
this.strIntoObjExp = JSON.parse(requesta.responseText);
var requestb = new XMLHttpRequest();
requestb.open('GET', 'http://localhost:6227/api/auth/users/' + id, false);
requestb.send(null);
this.specialUser = JSON.parse(requestb.responseText);
this.strIntoObjExp.forEach((exp: String) =>
{
if(exp.includes(this.specialUser.nameImage.substring(0, this.specialUser.nameImage.lastIndexOf("."))))
{
this.imagePath = exp;
}
});
return this.imagePath;
}
HTH
My html uses an ng-template. The template is to create thumbnails.
<ng-template #thumbnailTemplate let-option="option">
<div id="{{option.divId}}"> <!-- top level div of thumbnail. This will have ids thumbnail-1, thumbnail-2 etc.-->
<img id="{{option.imgId}}" src="{{option.imgSrc}}"> <!-- this will have width, height=80-->
<!-- the X button is created using CSS. This will have ids close-button-1, close-button-2. They'll also containn reference to the parent div id (thumbnail-1, thumbnail-2 ) -->
</div>
</ng-template>
The thumbnails gets created when a file is selected from an input element. FileReader sends load event and my event handler is called which should create a thumbnail by adding a view in the container
handleReaderLoaded(event:FileReaderProgressEvent) {
console.log("got load event of file reader ",event);
let thumbnailTemplateViewRef:EmbeddedViewRef<any>;
let imageString = event.target.result;//this will be like data:image/png;base64,ZGQ=ZGF0YTppbWFnZS9wbmc7YmFzZTY0LFpHUT0=
console.log("result from file load: ",imageString);
console.log("consecutive generator is ",this.consecutiveIdGenerator);
//create new ids for div, img and a in the template
++this.consecutiveIdGenerator;
let divId = "thumbnail-"+(this.consecutiveIdGenerator);
console.log("div id "+divId);
let imgId = "img-"+(this.consecutiveIdGenerator);
console.log("img id "+imgId);
let closeId = "close-button-"+(this.consecutiveIdGenerator);
console.log("close Id is "+closeId);
console.log("thumbnail container length was "+this.thumbnailContainerRef.length);
//TODOM - define context as a class so that it can be used in new question and question details
thumbnailTemplateViewRef = this.thumbnailContainerRef.createEmbeddedView(this.thumbnailTemplateRef,{option:{divId:divId,
imgId:imgId,
closeId:closeId,
imgSrc:imageString}});
//store the reference of the view in context of the template. This will be used later to retrive the index of the view when deleting the thumbnail
thumbnailTemplateViewRef.context.option.viewRefId = thumbnailTemplateViewRef;
console.log("thumbnail container length is "+this.thumbnailContainerRef.length);
}
Now I want to test handleReaderLoaded and check that it updates the thumbnailContainerRef by adding thumbnailTemplateViewRef in it.
The spec I have written is
fit('should upload image if user selects an image', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
expect(newPracticeQuestionComponent.thumbnailContainerRef.length).toBe(0);
let file1 = new File(["foo1"], "foo1.txt");
let reader = newPracticeQuestionComponent.handleFileSelect([file1]);//the callback for FileReader load method is assigned in this function. The callback is handleReaderLoaded
fixture.detectChanges();
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(1);
expect(newPracticeQuestionComponent.thumbnailContainerRef.length).toBe(1);
done(); //wait
console.log('done here');
});
My test case is failing because expect(newPracticeQuestionComponent.thumbnailContainerRef.length).toBe(1); is coming out as 0.
What am I doing wrong?
seems, I didn't understand the purpose of done correctly. I thought if I'll use done, the script will automatically wait but it doesn't (as is clear from the following trace)
reading file --> this is in handleFileSelect
context.js:1972 done here -->ths is in handleFileSelect
context.js:1972 got load event of file reader ProgressEvent {isTrusted: true, lengthComputable: true, loaded: 4, total: 4, type: "load", …} --> this is in the callback handleReaderLoaded. So the spec finished before the callback was called.
I done acts as a checkpoint in Jasmine. When Jasmine sees that a spec uses done, it knows that it cannot proceed to the next step (say run next spec) unless the code leg containing done has been called.
I re-wrote the spec to and created the checkpoint using done as follows
it('should upload image if user selects an image', (done) => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
expect(newPracticeQuestionComponent.thumbnailContainerRef.length).toBe(0);
let imageThumbnailDiv = fixture.debugElement.query(By.css("#thumbnail-1"));
let imageThumbnailImg = fixture.debugElement.query(By.css('#img-1'));
let imageThumbnailClose = fixture.debugElement.query(By.css('#close-button-1'));
//there should not be any HTML code which contains thumbnail
expect(imageThumbnailDiv).toBeFalsy();
expect(imageThumbnailImg).toBeFalsy();
expect(imageThumbnailClose).toBeFalsy();
let file1 = new File(["foo1"], "foo1.txt");
let reader = newPracticeQuestionComponent.handleFileSelect([file1]);
//file upload is async. so give time for `load` event of FileReader to be triggered and handled
setTimeout(function() {
console.log("in timeout");
fixture.detectChanges();//without this, the view will not be updated with model
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(1);
expect(newPracticeQuestionComponent.thumbnailContainerRef.length).toBe(1);
//the html for thumbnail should be created now
let imageThumbnailDiv2 = fixture.debugElement.query(By.css("#thumbnail-1"));
let imageThumbnailImg2= fixture.debugElement.query(By.css('#img-1'));
let imageThumbnailClose2 = fixture.debugElement.query(By.css('#close-button-1'));
expect(imageThumbnailDiv2).toBeTruthy();
expect(imageThumbnailImg2).toBeTruthy();
expect(imageThumbnailClose2).toBeTruthy();
done();//without done, jasmine will finish this test spec without checking the assertions in the timeout
}, 2000);
//if done is not use, jasmine will just finish the current spec without checking any assertions
});
Apparently Protractor cannot find this element in a menu on my application, elements above are ok. My code is:
this.openMenu("toogleMenuButton")
let prodLink = element(by.id("menu12"));
if (prodLink.isPresent()) {
prodLink.click();
browser.sleep(500);
} else {
return false;
}
The HTML code is:
<a _ngcontent-c13=""
appaccordiontoggle=""
class="relative mat-ripple"
md-ripple=""
routerlinkactive="open"
style="margin-left: 47px"
ng-reflect-class-base="relative"
ng-reflect-router-link-active="open"
id="menu12">
<span _ngcontent-c13="">Produtos</span>
</a>
Could someone help me please?
You need code to wait element to be visible (present in DOM and also visible - have height and width greater that 0). I put wait of 30s:
var EC = protractor.ExpectedConditions;
var prodlink = element(by.id('menu12'));
browser.wait(EC.visibilityOf(element(by.id('menu12'))), 30000, "prod link element is not visible").then(function() {
prodlink.click();
}
Analysis:
Your code has wrong at
if (prodLink.isPresent())
As we know all Protractor APIs are Async and return promise. When Javascript Enginee executing this line, Javascript get a promise object not a boolean value, Actually this IF statement will always true, because promise object not null, and it's very possible protractor have not to detect the link present from page, because all communication with page are Async.
Solution:
The correct code as below:
this.openMenu("toogleMenuButton")
let prodLink = element(by.id("menu12"));
prodLink.isPresent().then(function(present){
if(present) {
prodLink.click();
return true;
}
return false;
});
My code just to point out your mistake, the correct way in coding to click the link should be as 'Sanja Paskova' way.