How to use append_body method in Slash

Best Python code snippet using slash

__init__.py

Source:__init__.py Github

copy

Full Screen

...19 A dictionary object to be inspected.20 :return:21 """22 r = _get_report()23 r.append_body(render.inspect(source))24def header(header_text: str, level: int = 1, expand_full: bool = False):25 """26 Adds a text header to the display with the specified level.27 :param header_text:28 The text to display in the header.29 :param level:30 The level of the header, which corresponds to the html header31 levels, such as <h1>, <h2>, ...32 :param expand_full:33 Whether or not the header will expand to fill the width of the entire34 notebook page, or be constrained by automatic maximum page width. The35 default value of False lines the header up with text displays.36 """37 r = _get_report()38 r.append_body(render.header(39 header_text,40 level=level,41 expand_full=expand_full42 ))43def text(value: str, preformatted: bool = False):44 """45 Adds text to the display. If the text is not preformatted, it will be46 displayed in paragraph format. Preformatted text will be displayed47 inside a pre tag with a monospace font.48 :param value:49 The text to display.50 :param preformatted:51 Whether or not to preserve the whitespace display of the text.52 """53 if preformatted:54 result = render_texts.preformatted_text(value)55 else:56 result = render_texts.text(value)57 r = _get_report()58 r.append_body(result)59 r.stdout_interceptor.write_source(60 '{}\n'.format(textwrap.dedent(value))61 )62def markdown(63 source: str = None,64 source_path: str = None,65 preserve_lines: bool = False,66 font_size: float = None,67 **kwargs68):69 """70 Renders the specified source string or source file using markdown and71 adds the resulting HTML to the notebook display.72 :param source:73 A markdown formatted string.74 :param source_path:75 A file containing markdown text.76 :param preserve_lines:77 If True, all line breaks will be treated as hard breaks. Use this78 for pre-formatted markdown text where newlines should be retained79 during rendering.80 :param font_size:81 Specifies a relative font size adjustment. The default value is 1.0,82 which preserves the inherited font size values. Set it to a value83 below 1.0 for smaller font-size rendering and greater than 1.0 for84 larger font size rendering.85 :param kwargs:86 Any variable replacements to make within the string using Jinja287 templating syntax.88 """89 r = _get_report()90 result = render_texts.markdown(91 source=source,92 source_path=source_path,93 preserve_lines=preserve_lines,94 font_size=font_size,95 **kwargs96 )97 r.library_includes += result['library_includes']98 r.append_body(result['body'])99 r.stdout_interceptor.write_source(100 '{}\n'.format(textwrap.dedent(result['rendered']))101 )102def json(**kwargs):103 """104 Adds the specified data to the the output display window with the105 specified key. This allows the user to make available arbitrary106 JSON-compatible data to the display for runtime use.107 :param kwargs:108 Each keyword argument is added to the CD.data object with the109 specified key and value.110 """111 r = _get_report()112 r.append_body(render.json(**kwargs))113 r.stdout_interceptor.write_source(114 '{}\n'.format(_json_io.dumps(kwargs, indent=2))115 )116def plotly(117 data: typing.Union[dict, list, typing.Any] = None,118 layout: typing.Union[dict, typing.Any] = None,119 scale: float = 0.5,120 figure: typing.Union[dict, typing.Any] = None,121 static: bool = False122):123 """124 Creates a Plotly plot in the display with the specified data and125 layout.126 :param data:127 The Plotly trace data to be plotted.128 :param layout:129 The layout data used for the plot.130 :param scale:131 The display scale with units of fractional screen height. A value132 of 0.5 constrains the output to a maximum height equal to half the133 height of browser window when viewed. Values below 1.0 are usually134 recommended so the entire output can be viewed without scrolling.135 :param figure:136 In cases where you need to create a figure instead of separate data137 and layout information, you can pass the figure here and leave the138 data and layout values as None.139 :param static:140 If true, the plot will be created without interactivity.141 This is useful if you have a lot of plots in your notebook.142 """143 r = _get_report()144 if not figure and not isinstance(data, (list, tuple)):145 data = [data]146 if 'plotly' not in r.library_includes:147 r.library_includes.append('plotly')148 r.append_body(render.plotly(149 data=data,150 layout=layout,151 scale=scale,152 figure=figure,153 static=static154 ))155 r.stdout_interceptor.write_source('[ADDED] Plotly plot\n')156def table(157 data_frame,158 scale: float = 0.7,159 include_index: bool = False,160 max_rows: int = 500,161 sample_rows: typing.Optional[int] = None,162 formats: typing.Union[163 str,164 typing.Callable[[typing.Any], str],165 typing.Dict[166 str,167 typing.Union[str, typing.Callable[[typing.Any], str]]168 ]169 ] = None170):171 """172 Adds the specified data frame to the display in a nicely formatted173 scrolling table.174 :param data_frame:175 The pandas data frame to be rendered to a table.176 :param scale:177 The display scale with units of fractional screen height. A value178 of 0.5 constrains the output to a maximum height equal to half the179 height of browser window when viewed. Values below 1.0 are usually180 recommended so the entire output can be viewed without scrolling.181 :param include_index:182 Whether or not the index column should be included in the displayed183 output. The index column is not included by default because it is184 often unnecessary extra information in the display of the data.185 :param max_rows:186 This argument exists to prevent accidentally writing very large data187 frames to a table, which can cause the notebook display to become188 sluggish or unresponsive. If you want to display large tables, you need189 only increase the value of this argument.190 :param sample_rows:191 When set to a positive integer value, the DataFrame will be randomly192 sampled to the specified number of rows when displayed in the table.193 If the value here is larger than the number of rows in the DataFrame,194 the sampling will have no effect and the entire DataFrame will be195 displayed instead.196 :param formats:197 An optional dictionary that, when specified, should contain a mapping198 between column names and formatting strings to apply to that column199 for display purposes. For example, ``{'foo': '{:,.2f}%'}`` would200 transform a column ``foo = [12.2121, 34.987123, 42.72839]`` to201 display as ``foo = [12.21%, 34.99%, 42.73%]``. The formatters should202 follow the standard Python string formatting guidelines the same as203 the ``str.format()`` command having the value of the column as the only204 positional argument in the format arguments. A string value can also205 be specified for uniform formatting of all columns (or if displaying206 a series with only a single value).207 """208 r = _get_report()209 r.append_body(render.table(210 data_frame=data_frame,211 scale=scale,212 include_index=include_index,213 max_rows=max_rows,214 sample_rows=sample_rows,215 formats=formats216 ))217 r.stdout_interceptor.write_source('[ADDED] Table\n')218def svg(svg_dom: str, filename: str = None):219 """220 Adds the specified SVG string to the display. If a filename is221 included, the SVG data will also be saved to that filename within the222 project results folder.223 :param svg_dom:224 The SVG string data to add to the display.225 :param filename:226 An optional filename where the SVG data should be saved within227 the project results folder.228 """229 r = _get_report()230 r.append_body(render.svg(svg_dom))231 r.stdout_interceptor.write_source('[ADDED] SVG\n')232 if not filename:233 return234 if not filename.endswith('.svg'):235 filename += '.svg'236 r.files[filename] = svg_dom237def jinja(path: str, **kwargs):238 """239 Renders the specified Jinja2 template to HTML and adds the output to the240 display.241 :param path:242 The fully-qualified path to the template to be rendered.243 :param kwargs:244 Any keyword arguments that will be use as variable replacements within245 the template.246 """247 r = _get_report()248 r.append_body(render.jinja(path, **kwargs))249 r.stdout_interceptor.write_source('[ADDED] Jinja2 rendered HTML\n')250def whitespace(lines: float = 1.0):251 """252 Adds the specified number of lines of whitespace.253 :param lines:254 The number of lines of whitespace to show.255 """256 r = _get_report()257 r.append_body(render.whitespace(lines))258 r.stdout_interceptor.write_source('\n')259def image(260 filename: str,261 width: int = None,262 height: int = None,263 justify: str = 'left'264):265 """266 Adds an image to the display. The image must be located within the267 assets directory of the Cauldron notebook's folder.268 :param filename:269 Name of the file within the assets directory,270 :param width:271 Optional width in pixels for the image.272 :param height:273 Optional height in pixels for the image.274 :param justify:275 One of 'left', 'center' or 'right', which specifies how the image276 is horizontally justified within the notebook display.277 """278 r = _get_report()279 path = '/'.join(['reports', r.project.uuid, 'latest', 'assets', filename])280 r.append_body(render.image(path, width, height, justify))281 r.stdout_interceptor.write_source('[ADDED] Image\n')282def html(dom: str):283 """284 A string containing a valid HTML snippet.285 :param dom:286 The HTML string to add to the display.287 """288 r = _get_report()289 r.append_body(render.html(dom))290 r.stdout_interceptor.write_source('[ADDED] HTML\n')291def workspace(show_values: bool = True, show_types: bool = True):292 """293 Adds a list of the shared variables currently stored in the project294 workspace.295 :param show_values:296 When true the values for each variable will be shown in addition to297 their name.298 :param show_types:299 When true the data types for each shared variable will be shown in300 addition to their name.301 """302 r = _get_report()303 data = {}304 for key, value in r.project.shared.fetch(None).items():305 if key.startswith('__cauldron_'):306 continue307 data[key] = value308 r.append_body(render.status(data, values=show_values, types=show_types))309def pyplot(310 figure=None,311 scale: float = 0.8,312 clear: bool = True,313 aspect_ratio: typing.Union[list, tuple] = None314):315 """316 Creates a matplotlib plot in the display for the specified figure. The size317 of the plot is determined automatically to best fit the notebook.318 :param figure:319 The matplotlib figure to plot. If omitted, the currently active320 figure will be used.321 :param scale:322 The display scale with units of fractional screen height. A value323 of 0.5 constrains the output to a maximum height equal to half the324 height of browser window when viewed. Values below 1.0 are usually325 recommended so the entire output can be viewed without scrolling.326 :param clear:327 Clears the figure after it has been rendered. This is useful to328 prevent persisting old plot data between repeated runs of the329 project files. This can be disabled if the plot is going to be330 used later in the project files.331 :param aspect_ratio:332 The aspect ratio for the displayed plot as a two-element list or333 tuple. The first element is the width and the second element the334 height. The units are "inches," which is an important consideration335 for the display of text within the figure. If no aspect ratio is336 specified, the currently assigned values to the plot will be used337 instead.338 """339 r = _get_report()340 r.append_body(render_plots.pyplot(341 figure,342 scale=scale,343 clear=clear,344 aspect_ratio=aspect_ratio345 ))346 r.stdout_interceptor.write_source('[ADDED] PyPlot plot\n')347def bokeh(model, scale: float = 0.7, responsive: bool = True):348 """349 Adds a Bokeh plot object to the notebook display.350 :param model:351 The plot object to be added to the notebook display.352 :param scale:353 How tall the plot should be in the notebook as a fraction of screen354 height. A number between 0.1 and 1.0. The default value is 0.7.355 :param responsive:356 Whether or not the plot should responsively scale to fill the width357 of the notebook. The default is True.358 """359 r = _get_report()360 if 'bokeh' not in r.library_includes:361 r.library_includes.append('bokeh')362 r.append_body(render_plots.bokeh_plot(363 model=model,364 scale=scale,365 responsive=responsive366 ))367 r.stdout_interceptor.write_source('[ADDED] Bokeh plot\n')368def listing(369 source: list,370 ordered: bool = False,371 expand_full: bool = False372):373 """374 An unordered or ordered list of the specified *source* iterable where375 each element is converted to a string representation for display.376 :param source:377 The iterable to display as a list.378 :param ordered:379 Whether or not the list should be ordered. If False, which is the380 default, an unordered bulleted list is created.381 :param expand_full:382 Whether or not the list should expand to fill the screen horizontally.383 When defaulted to False, the list is constrained to the center view384 area of the screen along with other text. This can be useful to keep385 lists aligned with the text flow.386 """387 r = _get_report()388 r.append_body(render.listing(389 source=source,390 ordered=ordered,391 expand_full=expand_full392 ))393 r.stdout_interceptor.write_source('[ADDED] Listing\n')394def list_grid(395 source: list,396 expand_full: bool = False,397 column_count: int = 2,398 row_spacing: float = 1.0399):400 """401 An multi-column list of the specified *source* iterable where402 each element is converted to a string representation for display.403 :param source:404 The iterable to display as a list.405 :param expand_full:406 Whether or not the list should expand to fill the screen horizontally.407 When defaulted to False, the list is constrained to the center view408 area of the screen along with other text. This can be useful to keep409 lists aligned with the text flow.410 :param column_count:411 The number of columns to display. The specified count is applicable to412 high-definition screens. For Lower definition screens the actual count413 displayed may be fewer as the layout responds to less available414 horizontal screen space.415 :param row_spacing:416 The number of lines of whitespace to include between each row in the417 grid. Set this to 0 for tightly displayed lists.418 """419 r = _get_report()420 r.append_body(render.list_grid(421 source=source,422 expand_full=expand_full,423 column_count=column_count,424 row_spacing=row_spacing425 ))426 r.stdout_interceptor.write_source('[ADDED] List grid\n')427def latex(source: str):428 """429 Add a mathematical equation in latex math-mode syntax to the display.430 Instead of the traditional backslash escape character, the @ character is431 used instead to prevent backslash conflicts with Python strings. For432 example, \\delta would be @delta.433 :param source:434 The string representing the latex equation to be rendered.435 """436 r = _get_report()437 if 'katex' not in r.library_includes:438 r.library_includes.append('katex')439 r.append_body(render_texts.latex(source.replace('@', '\\')))440 r.stdout_interceptor.write_source('[ADDED] Latex equation\n')441def head(source, count: int = 5):442 """443 Displays a specified number of elements in a source object of many444 different possible types.445 :param source:446 DataFrames will show *count* rows of that DataFrame. A list, tuple or447 other iterable, will show the first *count* rows. Dictionaries will448 show *count* keys from the dictionary, which will be randomly selected449 unless you are using an OrderedDict. Strings will show the first450 *count* characters.451 :param count:452 The number of elements to show from the source.453 """454 r = _get_report()455 r.append_body(render_texts.head(source, count=count))456 r.stdout_interceptor.write_source('[ADDED] Head\n')457def tail(source, count: int = 5):458 """459 The opposite of the head function. Displays the last *count* elements of460 the *source* object.461 :param source:462 DataFrames will show the last *count* rows of that DataFrame. A list,463 tuple or other iterable, will show the last *count* rows. Dictionaries464 will show *count* keys from the dictionary, which will be randomly465 selected unless you are using an OrderedDict. Strings will show the466 last *count* characters.467 :param count:468 The number of elements to show from the source.469 """470 r = _get_report()471 r.append_body(render_texts.tail(source, count=count))472 r.stdout_interceptor.write_source('[ADDED] Tail\n')473def status(474 message: str = None,475 progress: float = None,476 section_message: str = None,477 section_progress: float = None,478):479 """480 Updates the status display, which is only visible while a step is running.481 This is useful for providing feedback and information during long-running482 steps.483 A section progress is also available for cases where long running tasks484 consist of multiple tasks and you want to display sub-progress messages485 within the context of the larger status.486 Note: this is only supported when running in the Cauldron desktop487 application.488 :param message:489 The status message you want to display. If left blank the previously490 set status message will be retained. Should you desire to remove an491 existing message, specify a blank string for this argument.492 :param progress:493 A number between zero and one that indicates the overall progress for494 the current status. If no value is specified, the previously assigned495 progress will be retained.496 :param section_message:497 The status message you want to display for a particular task within a498 long-running step. If left blank the previously set section message499 will be retained. Should you desire to remove an existing message,500 specify a blank string for this argument.501 :param section_progress:502 A number between zero and one that indicates the progress for the503 current section status. If no value is specified, the previously504 assigned section progress value will be retained.505 """506 environ.abort_thread()507 r = _get_report()508 step = _cd.project.get_internal_project().current_step509 changes = 0510 has_changed = step.progress_message != message511 if message is not None and has_changed:512 changes += 1513 step.progress_message = message514 has_changed = step.progress_message != max(0, min(1, progress or 0))515 if progress is not None and has_changed:516 changes += 1517 step.progress = max(0.0, min(1.0, progress))518 has_changed = step.sub_progress_message != section_message519 if section_message is not None and has_changed:520 changes += 1521 step.sub_progress_message = section_message522 has_changed = step.sub_progress != max(0, min(1, section_progress or 0))523 if section_progress is not None and has_changed:524 changes += 1525 step.sub_progress = section_progress526 if changes > 0:527 # update the timestamp to inform rendering that a status528 # has changed and should be re-rendered into the step.529 r.update_last_modified()530def code_block(531 code: str = None,532 path: str = None,533 language_id: str = None,534 title: str = None,535 caption: str = None536):537 """538 Adds a block of syntax highlighted code to the display from either539 the supplied code argument, or from the code file specified540 by the path argument.541 :param code:542 A string containing the code to be added to the display543 :param path:544 A path to a file containing code to be added to the display545 :param language_id:546 The language identifier that indicates what language should547 be used by the syntax highlighter. Valid values are any of the548 languages supported by the Pygments highlighter.549 :param title:550 If specified, the code block will include a title bar with the551 value of this argument552 :param caption:553 If specified, the code block will include a caption box below the code554 that contains the value of this argument555 """556 environ.abort_thread()557 r = _get_report()558 r.append_body(render.code_block(559 block=code,560 path=path,561 language=language_id,562 title=title,563 caption=caption564 ))565 r.stdout_interceptor.write_source('{}\n'.format(code))566def elapsed():567 """568 Displays the elapsed time since the step started running.569 """570 environ.abort_thread()571 step = _cd.project.get_internal_project().current_step572 r = _get_report()573 r.append_body(render.elapsed_time(step.elapsed_time))574 result = '[ELAPSED]: {}\n'.format(timedelta(seconds=step.elapsed_time))...

Full Screen

Full Screen

buckets.py

Source:buckets.py Github

copy

Full Screen

...15 try:16 patterns = [re.compile(arg) for arg in args]17 buckets = [{"bucket": bucket.name} for bucket in self.find_matching(patterns)]18 if len(buckets) == 0:19 self.resp.append_body([], template="empty_result")20 else:21 self.resp.append_body({"buckets": buckets}, template="list_buckets")22 except Exception as e:23 Logger.error("Regex compilation error: %s" % (e))24 self.resp.send_error("Invalid regular expression: '%s'" % (self.req.arg(0)))25 def handle_rm(self):26 self.handle_delete()27 def handle_delete(self):28 if self.req.arg_count() < 2:29 self.usage_error()30 args = self.req.args()31 try:32 patterns = [re.compile(arg) for arg in args[1:]]33 buckets = self.find_matching(patterns)34 try:35 for bucket in buckets:36 bucket.delete()37 except Exception as e:38 bucketnames = [bucket.name for bucket in buckets]39 Logger.error("Error deleting S3 buckets (%s): %s" % (bucketnames, e))40 self.resp.send_error("Error deleting buckets '%s': %s" % (bucketnames, e))41 if len(buckets) == 0:42 self.resp.append_body([], template="empty_result")43 else:44 bucket_names = [bucket.name for bucket in buckets]45 self.resp.append_body({"buckets": bucket_names}, template="delete_buckets")46 except Exception as e:47 self.resp.send_error("One of the following regular expressions is invalid: %s, %s" % (args[1:], e))48 def handle_create(self):49 self.handle_new()50 def handle_new(self):51 if self.req.arg_count() < 2:52 self.usage_error()53 buckets = self.req.args()[1:]54 errors = []55 for bucketname in buckets:56 try:57 bucket = self.conn.create_bucket(bucketname)58 except S3CreateError:59 errors.append(bucketname)60 except Exception as e:61 self.resp.send_error("There was a problem creating the S3 bucket(s): %s" % (e))62 if len(errors) == 1:63 self.resp.send_error("The bucket name `%s` is not a unique name. Please choose a different name." % (errors[0]))64 elif len(errors) > 1:65 self.resp.send_error("The bucket names: `%s` are not unique names. Please choose different names." % (", ".join(errors)))66 else:67 self.resp.append_body({"buckets": buckets}, template="create_buckets")68class BucketAclCommand(S3Command):69 possible_policies = ["public-read",70 "private",71 "public-read-write",72 "authenticated-read"]73 def prepare(self):74 self.connect()75 # Set the args and options76 self.selected_bucket = self.req.option("bucket") or ""77 self.specified_file = self.req.option("file") or ""78 self.policy = self.req.option("policy") or ""79 self.force = self.req.option("force") or False80 buckets = self.filter_buckets(self.selected_bucket, self.get_buckets())81 self.file_keys = self.get_filtered_keys(buckets)82 self.handlers["default"] = self.handle_list83 def get_acl(self, file_key):84 return file_key.get_acl()85 def set_acl_policies(self):86 fkey_names = ', '.join([fkey.bucket.name+":"+fkey.name for fkey in self.file_keys])87 if self.force:88 for file_key in self.file_keys:89 file_key.set_acl(self.policy)90 self.resp.append_body({"policy": self.policy, "file_keys": fkey_names},91 template="set_policy")92 else:93 self.resp.append_body({"policy": self.policy, "file_keys": fkey_names}, template="potential_set_policy")94 def package(self):95 prepared_acls = []96 for fkey in self.file_keys:97 acp = fkey.get_acl()98 prepared_acls.append({"bucket": fkey.bucket.name,99 "name": fkey.name,100 "grants": [{"name": grant.display_name,101 "uri": grant.uri,102 "permission": grant.permission,103 "email": grant.email_address} for grant in acp.acl.grants]})104 return prepared_acls105 def handle_list(self):106 self.resp.append_body({"acls": self.package()}, template="list_acls")107 def handle_set(self):108 if self.policy.lower() in self.possible_policies:109 self.set_acl_policies()110 else:111 self.resp.send_error("Error Unknown policy. Set to one of the following: 'public-read, private, public-read-write, authenticated-read'.")112 def usage_error(self):113 self.resp.send_error("s3-bucket-acl [set|list] [--policy=[public-read, private, public-read-write, authenticated-read] --force] <bucket name> <filename>")114class BucketFileCommand(S3Command):115 def prepare(self):116 self.connect()117 # Set the args and options118 self.selected_bucket = self.req.option("bucket") or ""119 self.specified_file = self.req.option("file") or ""120 self.force = self.req.option("force") or False121 buckets = self.filter_buckets(self.get_buckets())122 self.file_keys = self.get_filtered_keys(buckets)123 self.handlers["default"] = self.handle_list124 def delete_filekeys(self):125 try:126 for file_key in self.file_keys:127 file_key.delete()128 except:129 return False130 else:131 return True132 def handle_delete(self):133 file_keynames = ', '.join([file_key.bucket.name+':'+file_key.name for file_key in self.file_keys])134 if not self.force:135 self.resp.append_body({"file_keys": file_keynames}, template="potential_delete_bucket_files")136 elif self.force and self.delete_filekeys():137 self.resp.append_body({"file_keys": file_keynames}, template="delete_bucket_files")138 else:139 self.resp.send_error("Error deleting file keys")140 def package(self):141 return [{"name": file_key.name,142 "bucket": file_key.bucket.name} for file_key in self.file_keys]143 def handle_list(self):144 self.resp.append_body({"file_paths": self.package()}, template="list_bucket_files")145 def usage_error(self):...

Full Screen

Full Screen

main.py

Source:main.py Github

copy

Full Screen

...60 if continue_to_post.lower() in ['y', 'yes']:61 try:62 reddit = Bot.RedditInstance('PICPA_La_Robot', user_agent='script/PICPA_La_Robot')63 reddit.post_title = (f"This is PICPA for the week ending {end_date.strftime('%B %d, %Y')}")64 reddit.append_body('# PICPA WEEKLY')65 reddit.append_body('These are summary of new PICPA Events from', end=' ')66 reddit.extend_body_last(f"{last_week.strftime('%b %d')} to {end_date.strftime('%b %d')}.")67 reddit.append_body('You can register for these events at the', end=' ')68 reddit.extend_body_last('[PICPA GlueUp website](https://picpa.glueup.com/).', end='\n\n')69 reddit.append_body(contents)70 71 reddit.append_body('^(I am a bot in alpha. For concerns, contact', end=' ')72 reddit.extend_body_last('[tagapagtuos](https://www.reddit.com/user/tagapagtuos).)')73 reddit.post('AccountingPH')74 for item in comments:75 reddit.comment_on_post(item)76 except Exception as e:77 print(e)78 else:...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Slash automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful