How can I upload a PDF file using Karate UI Automation? [duplicate] - user-interface

This question already has answers here:
About Karate UI Test Automation, How can I upload files when I use karate-chrome?
(2 answers)
Closed 1 year ago.
Related the issue: Can upload / download files at Karate Driver?, Could you please help me to create the karate Ui code for upload excel PDF in this structure:
<div class="col-sm-6">
<div class="form-group shiny-input-container">
<label>Faça o upload do seu arquivo</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default btn-file">
Browse...
<input id="file_input" name="file_input" type="file" style="display: none;" data-shinyjs-resettable-id="file_input" data-shinyjs-resettable-type="File" data-shinyjs-resettable-value="" class="shinyjs-resettable shiny-bound-input">
</span>
</label>
<input type="text" class="form-control" placeholder="No file selected" readonly="readonly">
</div>
<div id="file_input_progress" class="progress progress-striped active shiny-file-input-progress">
<div class="progress-bar"></div>
</div>
</div>
</div>
I tried to use this source code below without success:
* def uri = 'http://the-internet.herokuapp.com/upload'
* def uploadSelector = '#file-upload'
* def submitSelector = '#file-submit'
# this function is for getting the full path of a file that is necessary to use with selenium sendKeys method when
# a file. I agree with the fact that every folder in Karate would contain the files used within the feature. Nevertheless
# having it results in a duplication of files if a lot of features use the same files. In this example I put the file in a
# separate folder. Maybe a Karate builtin function for retrieving the full path of a file in this specific case would be
# useful
* def fullPathFile =
"""
      function(arg) {
       return Java.type('examples.Utility').getFullPath(arg);
      }
"""
* def pdfFile = fullPathFile('files/pdf-test.pdf')
Given driver uri
And waitFor(uploadSelector).input(pdfFile)
When submit().click(submitSelector)
And delay(5000)
Then match driver.text('#content > div > h3') == 'File Uploaded!'
And match driver.text('#uploaded-files') contains 'pdf-test.pdf'

EDIT: first read this answer: https://stackoverflow.com/a/61904351/143475 - because the Chrome native integration supports driver.inputFile() which is available in 0.9.6.RC4
File upload is a well-known hard problem to solve in browser automation. We will need some contributions from the community, but here is a demo I just experimented with using Karate Robot: https://github.com/intuit/karate/tree/develop/karate-robot
Feature:
Scenario:
* driver 'http://the-internet.herokuapp.com/upload'
* robot { app: '^Chrome', highlight: true }
* robot.click('choose-file.png')
* robot.input('/Users/pthomas3/Desktop')
* robot.input(Key.ENTER)
* robot.click('file-name.png')
* robot.input(Key.ENTER)
* delay(1000)
* click('#file-submit')
* delay(2000)
* screenshot()
You can see a video of the execution here: https://twitter.com/ptrthomas/status/1253373486384295936
The other options I can think of:
a) Use Karate's API testing capabilities to perform a multipart file upload: https://github.com/intuit/karate#multipart-file - this is actually in most cases sufficient to "complete" the flow you have. For example for this exact same flow you see above, it looks like this:
* url 'http://the-internet.herokuapp.com/upload'
* multipart file file = { read: 'billie.png', filename: 'billie.png', contentType: 'image/png' }
* method post
And typically you may need to add a cookie or two, which you can easily pass from the browser to the API test / HTTP client.
b) The other option is something I haven't tried yet, you can "fake" the part of the UI that does the file-upload and replace it with something else, if it can get you forward in your flow. Refer this: https://twitter.com/KarateDSL/status/1248996522357739521

Related

Why do I get: cannot open file 'Documentation/workflow_accordion.html': No such file or directory

I am trying to add the shiny app into golem structure. Therefore, everything that I am asking here should be in line with golem structure.
Here is the problem:
I cannot add my html into a module. And that is why I get the following error:
cannot open file 'www/workflow_accordion.html': No such file or directory
Here is the module I have added to app_ui (make sure you see the golem structure here https://engineering-shiny.org/golem.html )
#' mod_workflows_ui
#'
#' #description A shiny Module.
#'
#' #param id,input,output,session Internal parameters for {shiny}.
#'
#' #noRd
#'
#' #importFrom shiny NS tagList
mod_workflows_ui <- function(id){
ns <- NS(id)
shiny::tabPanel(
"Workflows", icon = icon("list"),
div(
class = "container",
shinyLP::jumbotron(
"Workflows",
"How to use the Bioinformatics for the Bench apps to access specific datasets and answer biological questions",
button = FALSE
),
hr(),
includeHTML("Documentation/workflow_accordion.html"),
br(),
br(),
br()
)
)
tags$footer(
includeHTML("Documentation/footer.html")
)
}
#' mod_workflows_server
#'
#' #noRd
mod_workflows_server <- function(id){
ns <- session$ns
}
This module is added into several parts as per golem structure:
in app_server script as mod_workflows_ui("mod_workflows_ui_1")
in 02_dev - in dev folder as - golem::add_module(name = "workflow_app", with_test = TRUE)
After that I call in the mod_tutorials in app_ui file like this:
shiny::tabPanel("Workflow", icon = icon("graduation-cap"),mod_workflow_ui("mod_workflow_ui_1")),
And then I go int run_dev and just run the app.
Now the issue is that I get this error:
cannot open file 'Documentation/workflow_accordion.html': No such file or directory
What am I missing? Why does it do this and how I can solve it, I am open for other ways of solving this matter.
You must use app_sys to link your file:
includeHTML(app_sys("app", "www", "hello.html"))
When the application is launched, the path is evaluated in the context of the package and not in the context of the running application. Hence the need for a path to a package file.
I hope that's clear enough.
:)
Okay, I have 2 html's that I deal with above.
I will take only one example, the 'footer.html' since it is a bit harder to deal but because this is the exact pattern I have applied for the other html file.
But firstly, I have tried several ideas:
1. includeHTML("www/footer.html")
2. app_sys("app/www/footer.html")
Yet, none of these work. Apparently html files aren't specific to golem, according to #Colin Fay, as he mentioned here: https://github.com/ThinkR-open/golem/issues/890
Actually tried all his ideas and still, it did not work.
However,
what I have done was to take what was written in html and turn it into a module according to golem structure:
#' mod_footer_ui UI Function
#'
#' #description A shiny Module.
#'
#' #param id,input,output,session Internal parameters for {shiny}.
#'
#' #noRd
#'
#' #importFrom shiny NS tagList
mod_footer_ui <- function(id) {
ns <- NS(id)
tagList(
tags$footer(
HTML(
r"(
<div class="container">
<div class="row">
<div class="col-sm-3">
<img padding: 10px 10px; height="150px" src="www/logo_v4.png">
</div>
<div class="col-sm-3">
<h4>Links</h4>
<ul>
<li>goto.az/bftb</li>
<li>Workplace Group</li>
<li>Tutorial Recordings</li>
</ul>
</div>
<div class="col-sm-3">
<h4>About us</h4>
landing page was built by my name and other people's name. Please contact us with suggestions.
</div>
<div class="col-sm-3">
<h4>Support</h4>
<ul>
<li>Contact </li>
<li>Contact </li>
<li></li>
</ul>
</div>
</div>
</div>
<br>)
)"
)
)
)
}
#' mod_footer_server Server Functions
#'
#' #noRd
mod_footer_server <- function(id){
ns <- session$ns
}
Then adding these modules to golem scripts found in :
02_dev in dev folder as golem::add_module(name = "footer_app", with_test = TRUE)
app_server in R folder as mod_footer_ui("mod_footer_ui_1")
app_ui in R folder as tags$footer(mod_footer_ui("mod_footer_ui_1"))
Then run the script provided in golem run_dev and it works beautifully!

How to upload the file in karate UI automation sing single button from desktop [duplicate]

This question already has answers here:
About Karate UI Test Automation, How can I upload files when I use karate-chrome?
(2 answers)
Closed 1 year ago.
Related the issue: Can upload / download files at Karate Driver?, Could you please help me to create the karate Ui code for upload excel PDF in this structure:
<div class="col-sm-6">
<div class="form-group shiny-input-container">
<label>Faça o upload do seu arquivo</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default btn-file">
Browse...
<input id="file_input" name="file_input" type="file" style="display: none;" data-shinyjs-resettable-id="file_input" data-shinyjs-resettable-type="File" data-shinyjs-resettable-value="" class="shinyjs-resettable shiny-bound-input">
</span>
</label>
<input type="text" class="form-control" placeholder="No file selected" readonly="readonly">
</div>
<div id="file_input_progress" class="progress progress-striped active shiny-file-input-progress">
<div class="progress-bar"></div>
</div>
</div>
</div>
I tried to use this source code below without success:
* def uri = 'http://the-internet.herokuapp.com/upload'
* def uploadSelector = '#file-upload'
* def submitSelector = '#file-submit'
# this function is for getting the full path of a file that is necessary to use with selenium sendKeys method when
# a file. I agree with the fact that every folder in Karate would contain the files used within the feature. Nevertheless
# having it results in a duplication of files if a lot of features use the same files. In this example I put the file in a
# separate folder. Maybe a Karate builtin function for retrieving the full path of a file in this specific case would be
# useful
* def fullPathFile =
"""
      function(arg) {
       return Java.type('examples.Utility').getFullPath(arg);
      }
"""
* def pdfFile = fullPathFile('files/pdf-test.pdf')
Given driver uri
And waitFor(uploadSelector).input(pdfFile)
When submit().click(submitSelector)
And delay(5000)
Then match driver.text('#content > div > h3') == 'File Uploaded!'
And match driver.text('#uploaded-files') contains 'pdf-test.pdf'
EDIT: first read this answer: https://stackoverflow.com/a/61904351/143475 - because the Chrome native integration supports driver.inputFile() which is available in 0.9.6.RC4
File upload is a well-known hard problem to solve in browser automation. We will need some contributions from the community, but here is a demo I just experimented with using Karate Robot: https://github.com/intuit/karate/tree/develop/karate-robot
Feature:
Scenario:
* driver 'http://the-internet.herokuapp.com/upload'
* robot { app: '^Chrome', highlight: true }
* robot.click('choose-file.png')
* robot.input('/Users/pthomas3/Desktop')
* robot.input(Key.ENTER)
* robot.click('file-name.png')
* robot.input(Key.ENTER)
* delay(1000)
* click('#file-submit')
* delay(2000)
* screenshot()
You can see a video of the execution here: https://twitter.com/ptrthomas/status/1253373486384295936
The other options I can think of:
a) Use Karate's API testing capabilities to perform a multipart file upload: https://github.com/intuit/karate#multipart-file - this is actually in most cases sufficient to "complete" the flow you have. For example for this exact same flow you see above, it looks like this:
* url 'http://the-internet.herokuapp.com/upload'
* multipart file file = { read: 'billie.png', filename: 'billie.png', contentType: 'image/png' }
* method post
And typically you may need to add a cookie or two, which you can easily pass from the browser to the API test / HTTP client.
b) The other option is something I haven't tried yet, you can "fake" the part of the UI that does the file-upload and replace it with something else, if it can get you forward in your flow. Refer this: https://twitter.com/KarateDSL/status/1248996522357739521

Upload file to S3 using Ajax and Boto3 for Django

I have a django project in which I would like to upload all images to S3. I have installed boto3 and am able to print out my buckets. Thus I know I have a definite connection. Now my next step is to push a file to S3 using ajax. Below is the current setup I have. Will this approach work? One problem I have stumbled upon is the fact that Chrome returns C:\fakepath\filename.
Django view:
def change_project_image(request):
image = request.POST['image']
data = open(image, 'rb')
s3.Bucket('bucket-name').put_object(Key='filename.jpg', Body=data)
return HttpResponse('temporary return')
Javascript:
$('#project-image-upload').on('change', function(){
var image = $(this).val();
$.post('/project/change-project-image/', {image:image} function(data){
}, 'json');
});
HTML:
<label class="btn btn-default btn-file">
Browse <input id="project-image-upload" type="file">
</label>
So I took a different approach and was able to access the object in the view. I added the input to a form which posts to my desired view and then I handle the file like so:
def change_project_image(request):
image = request.FILES['image']
#now I need to pull the temporary path of image and pass it to boto
data = open('path_to_file', 'rb')
s3.Bucket('bucket_name').put_object(Key='filename.jpg', Body=data)
The problem I had was that I forgot to add enctype="multipart/form-data" in my form so request.FILES['image'] was empty.

How to use ajax in Brython

I am writing a web application using Flask and would like to use browser.ajax functionality in Brython but couldn't find a workable example. It would be very nice if someone demonstrates a short example how to use ajax in Brython. More specifically, how to pass data entered by a user into a textfield to a textarea by clicking submit button. Any help is highly appreciated!
(I am writing this several weeks after I posted the question above). I followed this tutorial on how to implement ajax in Flask (http://runnable.com/UiPhLHanceFYAAAP/how-to-perform-ajax-in-flask-for-python) and tried to replace jquery.ajax by Brython. Unfortunately, I still cannot get it work. Here is my code:
Flask's portion:
#app.route('/')
def index():
return render_template('index.html')
#app.route('/_add_numbers')
def add_numbers():
a = request.args.get('a', 0, type=int)
b = request.args.get('b', 0, type=int)
return jsonify(result=a + b)
Brython/HTML:
<body onload="brython()">
<script type="text/python">
from browser import document as doc
from browser import ajax
def on_complete(req):
if req.status==200 or req.status==0:
doc["txt_area"].html = req.text
else:
doc["txt_area"].html = "error "+req.text
def get(url):
req = ajax.ajax()
a = doc['A'].value
b = doc['B'].value
req.bind('complete',on_complete)
req.open('GET',url,True)
req.set_header('content-type','application/x-www-form-urlencoded')
req.send({"a": a, "b":b})
doc['calculate'].bind('click',lambda ev:get('/_add_numbers'))
</script>
<div class="container">
<div class="header">
<h3 class="text-muted">How To Manage JSON Requests</h3>
</div>
<hr/>
<div>
<p>
<input type="text" id="A" size="5" name="a"> +
<input type="text" id ="B" size="5" name="b"> =
<textarea type="number" class="form-control" id="txt_area" cols="10" rows = '10'></textarea>
<p>calculate server side
</div>
</div>
</body>
</html>
What I get is "result":0. It looks like brython does not send data to the Flask's view function but I don't know how to fix that. So, it would be great if some one could point out what exactly I am doing wrong.
In your example, the Ajax request is sent with the method GET. In this case, the argument of send() is ignored : the data must be sent in the query string appended to the url
The Brython code should be :
def get(url):
req = ajax.ajax()
a = doc['A'].value
b = doc['B'].value
req.bind('complete',on_complete)
# pass the arguments in the query string
req.open('GET',url+"?a=%s&b=%s" %(a, b),True)
req.set_header('content-type','application/x-www-form-urlencoded')
req.send()
If you want to use the POST method, then you can keep the Brython code as is, but the Flask code should be modified : you must specify that the function handles a POST request, and you get the arguments with the attribute "form" instead of "args" :
#app.route('/_add_numbers_post', methods=['POST'])
def add_numbers_post():
a = request.form.get('a', 0, type=int)
b = request.form.get('b', 0, type=int)
return jsonify(result = a+b)
I am working on that - there is nothing ready made, but writing Python code makes it really painless.
I can't post the code I am working on, (and it is far from minimal) - but basically, you write a (Br)Python function to iterate on the HTML, or form DOM, and collect everything that has a "value" in a json-nish structure (a dictionary with nested dicionaries and lists at will) - Them you simply use the browser.ajax object as documented in http://brython.info/doc/en/index.html#, and pass the object with your data as a parameter to the "send" method.
The object data will be URLencoded in the request body. You just have to decode it from there to JSON on the client side.
As an extra hint:
I did not go deep on the question, but I feel like the URLencoding used by default may fail to express everything that is possible in JSON. So imported brython's json module, and do the send like this:
ajax_object.send({"data": json.dumps(json_data)})
This allows me to do this on the client-side:
json_data = json.loads(urllib.unquote(request.body).split(":",1)[-1] )
(the "request.body" is from Pyramid - for flask it is "request.data", but only if the conte-type is not understood by the flask - check How to get data received in Flask request )

TYPO3 - geting images from a folder using Typoscript

I try to read pics (for a slider) from a folder. I have a marker called ###SLIDER### and my images are in the fileadmin/sliders/ folder.
I would like to achieve the following output as in the template that I bought:
<div class="camera_wrap">
<div data-src="fileadmin/sliders/slider_1.jpg">
<div class="camera-caption fadeIn">Text_1</div>
</div>
<div data-src="fileadmin/sliders/slider_2.jpg">
<div class="camera-caption fadeIn">Text_2</div>
</div>
<div data-src="fileadmin/sliders/slider_3.jpg">
<div class="camera-caption fadeIn">Text_3</div>
</div>
</div>
How can I load the images from a folder using Typoscript and display it this way?
The following code will give you what you want but without the captions. It works in TYPO3 4.5.x. I'm not sure that it works in higher versions as the description of filelist in the current (as of 16/10/2013) manual is somewhat confusing so I don't know if something has changed in the newer versions.
YOUR_MARKER = TEXT
YOUR_MARKER {
filelist = fileadmin/sliders/
split {
token = ,
cObjNum = 1
1 {
current = 1
wrap = <div data-src="fileadmin/sliders/|"></div>
}
}
wrap = <div class="camera_wrap">|</div>
}
NOTE: This is a very simple example that presumes that all the images in the folder are already resized to appropriate dimensions and that all the files within the folder are images. To make it better, the first (1) object of the split might be set to be IMG_RESOURCE. This way it would check that only images are outputted and it would allow you to use GIFBUILDER to resize the images if needed.

Resources