I faced with very strange problem. I had a set of tests which I run daily on Jenkins and without any noticeable changes some asserts(expects) started fail. THe strange thing here is that they fails ONLY if I execute tests from Jenkins on Browserstack. Locally everything just fine, locally on browserstack everything is fine, on saucelabs everything is fine. I have 3 it() blocks with similar expects:
value1 = $('.someclass');
value2 = ..
value3 = ..
expect(value1.getText()).toContain('tratata');
expect(value2.getText()).toContain('uhuhuhu');
expect(value3.getText()).toContain('ahahaha');
they are all situated in different it() blocks. Now strange thing:
When I execute tests, test with 1st assert block passes just fine, on the 2nd it block it says that assert fails(i do some stuff in order to change values), but manually / locally I see that everything is fine. Also while test is getting executed I see that values are getting changed ( i even did screenshots and check visual log on browserstack). In the 3rd it block I did other action and assert fails again, BUT it compare it with value which I was expected from step 2, not step 1!! SO looks like for some reason I am one step behind... If I comment it block or just asserts in the 1st test, 2nd one passes fine, but 3 fails. If I comment 2 it block, 3rd passes fine.
Sounds like that in this particular case for some reason some magic happens and only on Jenkins and only on Browserstack. By the way tests have been working for a while without any problems and started fail without any updates.
I though that for some reason I have problems with control flow, I WAIT for elements to be presented in addition, I tried browser.sleep() anti-pattern also to investigate it better, but it magically keeps be on the step behind.
I am not looking for particular solution directly, but any suggestions will be highly appreciated, I am not sure which additional info I should provide, hope I described the problem enough.
#protractor2.1.0
#jasmine2.3.2
browser.ignoreSynchronization = false
it('', function () {
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('542.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('4,878.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,420.00');
});
it('', function () {
$(viewBookingDetailsPage.eventAndItemsSection.addItemsBtn).click();
helper.waitElementToBeVisisble(viewBookingDetailsPage.addItemsModal.modalOpen);
viewBookingDetailsPage.addonItemAttribute(0, viewBookingDetailsPage.addItemsModal.events).click();
helper.waitElementToBeVisisble(viewBookingDetailsPage.addItemsModal.eventSelectionPopup);
viewBookingDetailsPage.addItemsModal.availableEvents.then(function (events) {
//Morning event
events[3].$('i').click();
viewBookingDetailsPage.addonItemAttribute(0, viewBookingDetailsPage.addItemsModal.selectItem).click();
viewBookingDetailsPage.addonItemAttribute(1, viewBookingDetailsPage.addItemsModal.selectItem).click();
viewBookingDetailsPage.addItemsModal.addButton.click();
helper.waitElementToDisappear(viewBookingDetailsPage.addItemsModal.modalOpen);
helper.waitElementToBeVisible(viewBookingDetailsPage.addonItemDetail(0, 0, 0, viewBookingDetailsPage.eventAndItemsSection.itemName));
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('592.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('5,328.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,920.00');
});
});
it('', function () {
viewBookingDetailsPage.addonItemDetail(0, 0, 0, viewBookingDetailsPage.eventAndItemsSection.removeItem).click(); ----- method just returns element into multiple internal repeaters
expect(viewBookingDetailsPage.totalCostSection.depositDue.getText()).toContain('580.00');
expect(viewBookingDetailsPage.totalCostSection.remainingBalance.getText()).toContain('5,220.00');
expect(viewBookingDetailsPage.totalCostSection.totalDepositAmount.getText()).toContain('5,800.00');
});
I fixed this with waiting directly to text to change:
browser.wait(function() {
return viewBookingDetailsPage.totalCostSection.depositDue.getText().then(function(text) {
return text === '592.00USD';
});
}, 15000);
I am sure that something goes wrong here, but it worked for me. If I will have some free time I will try to enhance the answer and investigate it deeper.
This post hints at the fact that one of the steps could be blocked waiting to complete: http://makandracards.com/makandra/1709-single-step-and-slow-motion-for-cucumber-scenarios-using-javascript-selenium. Not sure if that helps at all.
Related
OK, the docs are messy at best. I have huge issues fading in and out preloaded assets if I do not add 'false' to the instance of PreloadJS. But when I add it I completely lose the progress event ... what is it that's so deeply hidden in the docs, that I cannot find anything about this?
And has anyone got a complete example of HOW to actually and properly load an array (actually an object) of images without losing the progress event AND still have an asset that behaves as expected when adding it to the DOM and fade it in?
This was also posted in a question on GitHub.
The short answer is that loading with tags (setting the first param useXHR to false) doesn't support granular progress events because downloading images with tags doesn't give progress events in the browser.
You can still get progress events from the LoadQueue any time an image loads, but each image will just provide a single "complete" event.
#Lanny True for that part, but in my case I was also missing the 'true' in .getResult(), and the createObjectURL() for the image data:
…
var preloader = new createjs.LoadQueue();
…
…
function handleFileLoad ( e ) {
var item = e.item,
result = preloader.getResult(item.id, true),
blob_url = URL.createObjectURL( result );
…
So, that I was actually able to handle the image data as a blob … I couldn't find anything close to 'createObjectURL' in the docs. I guess that renders the docs 'not complete' at best …
I'm using NgBlockUI and BlockUIHttpModule with blockAllRequestsInProgress set to true in an app I'm working on. In general it's working fine, but on one page I'm using a concat map to perform some action and then update the data. The first request, the update, triggers BlockUI fine, but the second one doesn't. Otherwise, it executes properly. It's just a little jarring for the user since the results seem to update without warning. Here's the code for the function:
onUpdate(event: items[]) {
this.updateService.update(event).concatMap(
_ => this.seachService.search(this.cachedSearch)
).subscribe(
resp => this.handleResponse(resp),
err => this.handleError(err)
);
}
I tried calling BlockUI directly, but still no luck. As a last resort, I'm going to make the whole thing one request, but I'd like to at least understand why this isn't working.
This happened to me as well. This issue occurs for sequential HTTP calls (usually with await) wherein the second request is not blocked by ng-block-ui.
As fix what I did was set blockAllRequestsInProgress to false. The behavior is just the same but setting it to false yields more predictable results:
BlockUIHttpModule.forRoot({
blockAllRequestsInProgress: false,
requestFilters: [urlFilter]
}),
I've also updated to ng-block-ui to latest version as of this writing:
"ng-block-ui": "^2.1.8",
Assuming a scenario where DX12 is being hooked for overlay rendering it looks like the best function to hook is the IDXGISwapChain::Present the same way it was done for DX11. Having this function hooked the swap chain is available and from that the device can be retrieved to create resources. Given those resources it’s possible to record rendering commands too. The problem arises when we are trying to execute the rendering commands as there is no option to retrieve the associated command queue from the swap chain so there is nothing like this:
CComPtr<ID3D12Device> pD3D12Device;
if (pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)(&pD3D12Device)) == S_OK)
{
pD3D12Device->GetCommandQueueForSwapChain( swapChain )->ExecuteCommandLists(…);
}
The other option would be creating a new command queue to execute on, like this:
CComPtr<ID3D12Device> pD3D12Device;
if (pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)(&pD3D12Device)) == S_OK)
{
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
HRESULT commandQueueRes = _device->CreateCommandQueue( &queue_desc, IID_PPV_ARGS( &_commandQueue ) );
_commandQueue->ExecuteCommandLists( ... );
}
This results in an error and subsequent device removal. See the error message below.
D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: A command list, which writes to a swap chain back buffer, may only be executed on the command queue associated with that buffer. [ STATE_SETTING ERROR #907: EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE]
The problem is not resolved even if the ID3D12CommandQueue::ExecuteCommandLists is hooked as well because there is no way to retrieve the associated swap chain from the command queue either.
So my question is what is the recommended way to deal with this problem in a scenario where the swap chain creation happens before the hooking could possibly happen?
In case anyone is looking for the answer here's what I found out.
There is no official way to do this, for overlay rendering the recommended way is to use DirectComposition but this has performance consequences which is not very nice for game overlays.
Investigating the memory a bit there is a possible solution to get the CommandQueue from the swap chain with something like this:
#ifdef _M_X64
size_t* pOffset = (size_t*)((BYTE*)swapChain + 216);
#else
size_t* pOffset = (size_t*)((BYTE*)swapChain + 132);
#endif
*(&_commandQueue) = reinterpret_cast<ID3D12CommandQueue*>(*pOffset);
Obviously this solution is not recommended but it might be useful if someone just want's to do some debugging.
My final solution is to hook into a function that uses the CommandQueue (I use ExecuteCommandLists) and get the pointer there and use it later to render the overlay. It's not completely satisfying but it works as long as there are no multiple swap chains.
I want to examine http requests in an extension for firefox. To begin figuring out how to do what I want to do I figured I'd just log everything and see what comes up:
webRequest.onResponseStarted.addListener(
(stuff) => {console.log(stuff);},
{urls: [/^.*$/]}
);
The domain is insignificant, and I know the regex works, verified in the console. When running this code I get no logging. When I take out the filter parameter I get every request:
webRequest.onResponseStarted.addListener(
(stuff) => {console.log(stuff);}
);
Cool, I'm probably doing something wrong, but I can't see what.
Another approach is to manually filter on my own:
var webRequest = Components.utils.import("resource://gre/modules/WebRequest.jsm", {});
var makeRequest = function(type) {
webRequest[type].addListener(
(stuff) => {
console.log(!stuff.url.match(/google.com.*/));
if(!stuff.url.match(/google.com.*/))
return;
console.log(type);
console.log(stuff);
}
);
}
makeRequest("onBeforeRequest");
makeRequest("onBeforeSentHeaders");
makeRequest("onSendHeaders");
makeRequest("onHeadersReceived");
makeRequest("onResponseStarted");
makeRequest("onCompleted");
With the console.log above the if, I can see the regex returning true when I want it to and the code making it past the if. When I remove the console.log above the if the if no longer gets executed.
My question is then, how do I get the filtering parameter to work or if that is indeed broken, how can I get the code past the if to be executed? Obviously, this is a fire hose, and to begin searching for a solution I will need to reduce the data.
Thanks
urls must be a string or an array of match patterns. Regular expressions are not supported.
WebRequest.jsm uses resource://gre/modules/MatchPattern.jsm. Someone might get confused with the util/match-pattern add-on sdk api, which does support regular expressions.
I'm using symfony 1.4.8 and I have some code that basically looks like this (in a Filter):
$user = $this->getContext()->getUser();
if ($condition)
$user->addCredential('cred');
else
$user->removeCredential('cred');
die($user->hasCredential('cred');
No matter what I have done, it always registers that it has the cred credential. The die always outputs 1. I've even removed the if/else and just ran removeCredential() but it still dies with 1. Also of interest is that this is the ONLY place where this credential might be added (or removed), so I don't understand how I ALWAYS have it. I'm using sfDoctrineGuardUser plugin.
The following code is puzzling:
$user->removeCredential('cred');
var_dump($user->hasCredential('cred')); // bool(true)
also this:
var_dump($user->getCredentials()); // array(0) { }
var_dump($user->hasCredential('cred')); // bool(true)
I've also tried clearCredentials() with no luck. How can I remove this credential? I'm completely at a loss here.
Is your user a Super Admin? In such case hasCredential() always returns true.