cy.findByText - string substitution - cypress

delete(customData: Data): void {
const { name } = customData;
cy.findByText("Successfully removed `${name}`!", {timeout : 15000});
I'm not able to get this to work. Perhaps findByText() doesn't support this .
Is there another way I could do this ? The following message is an alert message and disappears in a few seconds after it's displayed. So, I'm unable to find the element locator for this alert message.
"Successfully removed name!"

You can use cy.contains() as an alternative to cy.findByText.
cy.contains(`Successfully removed ${name}!`, {timeout : 15000});
Or, If you want to use findByText you have to use this:
cy.findByText(`Successfully removed ${name}!`, {timeout : 15000});
You can learn more about Template literals from here.

You could also use this function:
function followLabel(label) {
return cy.contains('label', label)
.invoke('attr', 'for')
.then(id => cy.get('#' + id));
}
-> cy.followLable("Sucessfully removed");

Related

Combined resolvers always throw "cannot read property 'apply' of undefined" error

I am trying to attach the following guard:
export const isSupplier=(_,__,{me})=>{
me.role==="supplier" ? skip : new ForbiddenError('Not authenticated as supplier.');
}
To a resolver, like this:
addProductNow:combineResolvers(
isSupplier,
async (_,{name,price,description,url,stock},{dataSources,me})=>{
const supplierId=me.id
console.log(supplierId)
const supplier=await dataSources.SupplierAPI.findSupplierById(supplierId)
const newProduct=await dataSources.ProductAPI.addProduct(name,price,description,url,stock,supplierId,{ttlInSeconds:60*20})
return newProduct
}),
Yet it always returns the error "cannot read property 'apply' of undefined". I have tried to log something in the guard , yet it seems like it never gets executed. After removing the guard from the resolver everything works fine and logging 'me' shows the expected value. Am I doing something wrong ? Thanks !
I'm not sure what you're using for your "guards", but I assume it's because you're not doing or returning anything in this function, and it's expecting a function (what it calls "apply" on):
export const isSupplier=(_,__,{me})=>{
me.role==="supplier" ? skip : new ForbiddenError('Not authenticated as supplier.');
}
Did you mean to do this:
export const isSupplier=(_,__,{me})=>{
return me.role==="supplier" ? skip : new ForbiddenError('Not authenticated as supplier.');
}
Follow-up Edit:
From googling some of your variable names, I assume you're using graphql-resolvers.
In the example they provide, they use "arrow functions with implicit return", which is when you
Don't add Braces around the body of your function
Put the whole thing in one expression
The result of the function becomes whatever the expression after the arrow results in:
const isAuthenticated = (root, args, { user }) => user ? skip : new Error('Not authenticated')
This can be converted to using "explicit returns" by adding braces and the return keyword like this:
const isAuthenticated = (root, args, { user }) => {
return user ? skip : new Error('Not authenticated')
}
Your code as documented, however, added the braces but NOT the return and therefore always returns undefined. Looking at the source code of that library, if you don't return EXACTLY skip it resolves to whatever the return value of your function was (in this case undefined).
Can you share more information about your stack trace to show WHAT is trying to call .apply on what?

How can I call an async method when a button is clicked and avoid warning messages for message not returning void?

Here's the code that I have.
The IDE is giving me a warning line under the "async" in the 3rd line, that says "Asynchronous method must not return void"
public QHPageViewModel()
{
DeleteQuizCmd = new Command<string>(async (x) => await DeleteQuizAsync(x));
}
private async Task DeleteQuizAsync(string quizId)
{
var canContinue = await Shell.Current.DisplayAlert("Delete Quiz", "Do you want to delete the results for Quiz " + quizId, "OK", "Cancel");
if (canContinue == false)
return;
App.DB.DeleteQuizHistory(System.Convert.ToInt32(quizId));
UpdateQuizDetails();
}
Is there an issue with the way that this is coded, is there a better way to code this or should I just ignore this message? What are the consequences of ignoring the message?
It yells at you cause basic XF Commands don't have async capabilities.
If you want warnings to go away, you can write your own AsyncCommand implementing ICommand, or just use the AsyncCommand from stephen cleary: https://github.com/StephenCleary/Mvvm.Async/tree/master/src/Nito.Mvvm.Async
To avoid any warning, and keep the same logic you can also write:
if (await Shell.Current.DisplayAlert("Delete Quiz", "Do you want to delete the results for Quiz " + quizId, "OK", "Cancel"))
{
App.DB.DeleteQuizHistory(System.Convert.ToInt32(quizId));
UpdateQuizDetails();
}

How to remove tooManyAttempts message in Prompt.Choice? How to accept text in Prompt.Choice that is not in list of options? C#

I'm using bot-Framework SDK3 C#.
I want to allow user input anything which is not in "PromptDialog.Choice"'s options. Any better ways to recommend?
This is my code.
private async Task SelectCategory(IDialogContext context)
{
List<string> options = new List<string>();
options = category.Keys.ToList();
options.Add("Category1");
options.Add("Category2");
options.Add("Category3");
PromptOptions<string> promptOptions = new PromptOptions<string>(
prompt: "which one do you prefer?",
tooManyAttempts: "",
options: options,
attempts: 0);
PromptDialog.Choice(context: context, resume: ResumeAfterSelectCategory, promptOptions: promptOptions);
await Task.FromResult<object>(null);
}
private async Task ResumeAfterSelectCategory(IDialogContext context, IAwaitable<string> result)
{
try
{
selected = await result;
}
catch (Exception)
{
// if the user's input is not in the select options, it will come here
}
}
But the problem is it always send the message "tooManyAttempts". If I set it to empty, I will send me "0".
I suppose you are using NodeJS. You can use the simple builder.Prompts.choice with maxRetries set to 0. Here is a sample snippet. It asks user to choose some option from a list, or they can enter something which is not in the list.
If you are using C# SDK, you can find some similar option for the list.
bot.dialog("optionalList", [
function(session){
builder.Prompts.choice(
session,
"Click any button or type something",
["option1", "option2", "option3"],
{maxRetries: 0} // setting maxRetries to zero causes no implicit checking
)
},
function(session, result){
// something from the list has been clicked
if(result.response && result.response.entity){
console.log(result.response.entity); // use the clicked button
} else {
console.log(session.message.text) // if user entered something which is not in the list
}
}
]);
EDIT 1:
Hi, Saw that you are using C# SDK. I am not that proficient with that but I can give you some suggestion.
The list which you generate in the async task SelectCategory you can generate in some other place, which is also accessible to the second async task ResumeAfterSelectCategory, (like making it a class variable or getting from database).
Now that the list is accessible in the 2nd task, you can compare what user has typed against the list to determine if the message is from the list or not.
If message is something from the list, then take action accordingly, otherwise user has entered something which is not in the list, and then take action accordingly.
Your 2nd problem is
And if user typed, it will show a message "you tried to many times"
What is meant by that? Does bot sends "you tried to many times" to the bot visitor. In which case it could be the behavior of library. You will be able to control that only if library provides some option. Else I don't know. Hope, that helps
EDIT 2:
I came across this SO question Can I add custom logic to a Bot Framework PromptDialog for handling invalid answers?
You can use that questions answer. Basically extending PromptDialog.PromptChoice<T>.Here is an example.
Override TryParse method like this
protected override bool TryParse(IMessageActivity message, out T result)
{
bool fromList = base.TryParse(message, out result);
if (fromList)
{
return true;
} else {
// do something here
return true; // signal that parsing was correct
}
}
I used node.js and to get message which user entered. use this code snippet.
(session, args) => {
builder.Prompts.text(session, "Please Enter your name.");
},
(session, args) => {
session.dialogData.username = args.response;
session.send(`Your user name is `${session.dialogData.username}`);
}

Cannot pass ampersand and hash sign in MVC

I have this code
#using (Ajax.BeginForm("LoadFilter", "Contact", new { filterType = (int)FilterContactBy.Name }, new AjaxOptions { OnBegin = "ShowProgrees", OnSuccess = "HideProgress" }))
{
#Html.TextBoxFor(m => m.ContactFilter.FilterValue, new { placeholder = "Enter a name" })
<input type="submit" class="link submit green" value="Add Filter" />
}
As quite obvious, the ShowProgress and HideProgress method do nothing but show and hide a loader gif.
The method at backend is
[HttpPost]
public ActionResult LoadFilter(ContactListModel filter, int filterType=0, Boolean isAllFilterApply=true)
{
if (filter != null)
{
// process here
}
}
It works fine if I enter anything, for example
hi
test
me & you
contact #1
contact #1 and me
BUT
When I enter &# together in any from error occurs. The loader gif just keeps moving and the code on Controller is never hit.
Also, in Chrome console, it shows 500 Internal Server Error (and so does Firefox!).
My Solution
I tried escape and enocodeURIComponent but it didn't worked. Here's the method I tried
$.ajaxPrefilter(function(o, org, xhr) {
if (org.url.indexOf('/Contact/LoadFilter?filterType=') > -1) {
// console.log(org.data[0].value);
org.data[0].value = encodeURIComponent(org.data[0].value);
// console.log(org.data[0].value);
}
});
The output (in console)
&#
%26%23
When instead of encodeURIComponent I used escape, the output was same
&#
%26%23
But it still doesn't hit the method on controller. Can anyone please help me to get a solution, and more importantly, tell me why is this occurring in the first place?
ps
Please don't ask me that what is the use of inputting &# in a contact filter, or to remove these and tell client this is not a valid input. I can't do that, so please don't advice that.
Update
Is anyone even reading this fully? I am not asking that how can I decode. NO. Please read the full question before marking it as duplicate or marking it for close.
Okay, I got this.
I created Application_BeginRequest in Global.asax in the code like this..
protected void Application_BeginRequest(Object sender, EventArgs e)
{
var httpApp = (HttpApplication)sender;
Debug.Write(httpApp);
}
I sat a breakpoint of httpApp and then in the watch window, checked for httpApp.Request and found that it was there. It said (something I don't remember right now) threw an exception of type 'System.Web.HttpRequestValidationException'.
So, I got that the error was because of this, so on the method LoadFilter, I just added the attribute ValidateInput(false), and it's working
[HttpPost]
[ValidateInput(false)]
public ActionResult LoadFilter(ContactListModel filter, int filterType=0, Boolean isAllFilterApply=true)
{
// process here
}
Though, I do have to check for sql injection in here because we are building up a dynamic query from the input we receive.
Use
HttpUtility.UrlDecode("url")

Magento: ImageCdn bug? (long story)

I have some question related with Magento's free extension OnePica ImageCdn.
A broken image appear in frontend when I uploaded "corrupt image".
Ok, let's start the long story:
I notice it is happened because of ImageCdn extension and "corrupt image".
In some part of ImageCdn's code:
OnePica_ImageCdn_Helper_Image
/**
* In older versions of Magento (<1.1.3) this method was used to get an image URL.
* However, 1.1.3 now uses the getUrl() method in the product > image model. This code
* was added for backwards compatibility.
*
* #return string
*/
public function __toString()
{
parent::__toString();
return $this->_getModel()->getUrl();
}
My question is, anybody know what is the purpose of that code?
I don't understand what is the meaning of their comment above.
I think it is a bug as it always return $this->_getModel()->getUrl();
Is is really a bug or it is just my wrong interpretation?
This is what I've done so far:
I have an image dummy.jpeg
After some investigation, I just realized that is a "corrupt image".
I tested using: <?php print_r(getimagesize('dummy.jpeg')); ?>
Result:
Array
(
[0] => 200
[1] => 200
[2] => 6
[3] => width="200" height="200"
[bits] => 24
[mime] => image/x-ms-bmp
)
Of course I was surprised by the result because it looks good when I open it using Preview (on Mac OSX)
Then I open it using hex editor, the first two bytes is : BM which is BMP's identifier
I tried to upload .bmp image for product -> failed, can not select the image
I asked my colleague to upload it too (on Ubuntu), he was able to change the choices for file type into "any files". When he click "Upload Files", error message shown state that that type of file is not allowed.
What crossed on my mind is: an admin tried to upload .bmp image and failed. Then he rename it into .jpeg and successful. Though I don't get it what kind of images can be renamed without showing broken image logo (out of topic).
Those scenarios trigger an Exception, I'll break down what I've traced.
Trace of the codes:
app/design/frontend/base/default/catalog/product/view/media.phtml
<?php
$_img = '<img id="image" src="'.$this->helper('catalog/image')->init($_product, 'image').'" alt="'.$this->htmlEscape($this->getImageLabel()).'" title="'.$this->htmlEscape($this->getImageLabel()).'" />';
echo $_helper->productAttribute($_product, $_img, 'image');
?>
From that code, I know that image url is generated using: $this->helper('catalog/image')->init($_product, 'image')
I did Mage::log((string)$this->helper('catalog/image')->init($_product, 'image'));
Result:
http://local.m.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/d/u/dummy.jpeg
.
Mage_Catalog_Helper_Image
public function __toString()
{
try {
if( $this->getImageFile() ) {
$this->_getModel()->setBaseFile( $this->getImageFile() );
} else {
$this->_getModel()->setBaseFile( $this->getProduct()->getData($this->_getModel()->getDestinationSubdir()) );
}
if( $this->_getModel()->isCached() ) {
return $this->_getModel()->getUrl();
} else {
if( $this->_scheduleRotate ) {
$this->_getModel()->rotate( $this->getAngle() );
}
if ($this->_scheduleResize) {
$this->_getModel()->resize();
}
if( $this->getWatermark() ) {
$this->_getModel()->setWatermark($this->getWatermark());
}
Mage::log('pass');
$url = $this->_getModel()->saveFile()->getUrl();
Mage::log('not pass');
}
} catch( Exception $e ) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
return $url;
}
The error triggered in $this->_getModel()->saveFile()->getUrl(). In some part of the code, it will eventually reach:
Varien_Image_Adapter_Gd2
private function _getCallback($callbackType, $fileType = null, $unsupportedText = 'Unsupported image format.')
{
if (null === $fileType) {
$fileType = $this->_fileType;
}
if (empty(self::$_callbacks[$fileType])) {
//reach this line -> exception thrown
throw new Exception($unsupportedText);
}
if (empty(self::$_callbacks[$fileType][$callbackType])) {
throw new Exception('Callback not found.');
}
return self::$_callbacks[$fileType][$callbackType];
}
The exception was catched in the previous code:
Mage_Catalog_Helper_Image
public function __toString()
{
...
} catch( Exception $e ) {
$url = Mage::getDesign()->getSkinUrl($this->getPlaceholder());
}
...
}
the $url became:
http://local.m.com/skin/frontend/default/default/images/catalog/product/placeholder/image.jpg
So, it should have generated placeholder image right?
(without ImageCdn extension)
No, because
Mage_Catalog_Helper_Image was rewritten by
OnePica_ImageCdn_Helper_Image
public function __toString()
{
parent::__toString(); //the result is http://local.m.com/skin/frontend/default/default/images/catalog/product/placeholder/image.jpg but no variable store/process its value
return $this->_getModel()->getUrl(); //in the end it will return http://local.m.com/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/d/u/dummy.jpeg
}
In case you all already forgot the question:
Anybody know what is the purpose of that code? I don't understand what is the meaning of their comment above.
Is it really a bug or it is just my wrong interpretation?
No it isn't a bug. It's just legacy support for older Magento systems. I'm wondering, have you ever got around to snoop around earlier versions of magento (as the inline documentation comment references to, < 1.1.3)?
The gist of the matter is before Mage 1.1.3, Mage_Catalog_Helper_Image instances happen to produce URL's from to-string casts e.g.
$image = (some instance of Mage_Catalog_Helper_Image).. ;
$imageUrl = (string) $image;
__toString is probably either protected or private, i'm not sure but what I'm sure is the usual practice is to always code up this Magic Method in order to use it in a class that you are meaning to rewrite something with that expects to use this kind data cast.

Resources