Wait for CSS property - css

I have a problem with checking CSS properties in a Testcafe session.
I have a progres bar on the site with the html:
<div class="progress-bar progress-bar-success"></div>
When the operation is ready, this progress ba becomes a width of 100%.
<div class="progress-bar progress-bar-success" style="width: 100%;"></div>
In my code I use now the line
await t.expect(Selector('.progress-bar.progress-bar-success').getStyleProperty('width')).eql('100%', {timeout: 90000})
But it will not work. It waits the whole time until the waiting time has finished.
I use a similar function inside another run, where I wait for changing the color of an item with CSS and RGB, this works perfectly.
I think now the problem is, that the style is not available on startup. Or is there any other possibility?

The issue occurs because according to the docs the getStyleProperty method returns the computed value of width, which means that the value is returned in pixels, while you want to check the value in percents.
As a solution, I recommend you use the ClientFunctions mechanism, which allows you to get the desired value.
I prepared a sample for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.bar {
width: 500px;
height: 50px;
border: 1px solid black;
overflow: hidden;
}
.progress {
height: 100%;
background-color: black;
}
</style>
</head>
<body>
<div class="bar">
<div class="progress" style="width: 0;"></div>
</div>
<script>
setInterval(function () {
var progress = document.querySelector('.progress');
progress.style.width = Math.min(100, parseInt(progress.style.width) + 1) + '%';
}, 50);
</script>
</body>
</html>
And here is the test code:
import { Selector, ClientFunction } from 'testcafe';
fixture `progress`
.page `index.html`;
const getStyleWidthInPercents = ClientFunction(() => {
return document.querySelector('.progress').style.width;
});
test('progress', async t => {
await t.expect(getStyleWidthInPercents()).eql('100%', {timeout: 90000})
});

Related

How to overlay an image on webcam with start button

I cannot get the image to show over my webcam, I am a total newbie here so I have no clue what I am doing to get it positioned properly. I dont know where to put the div reference in the html and I don't understand positioning. The webcam starts with a button, then captures an image. I want some way of centering an overlay on the preview before the capture is taken.
I have included the html and the css at the bottom
Thank you in advance!!
!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- Name of your awesome camera app -->
<title>Measurement</title>
<!-- Link to your main style sheet-->
<link rel="stylesheet" href="StyleSheet1.css">
</head>
<body>
<button id="start-camera">Start Camera</button>
<video id="video" width="320" height="240" autoplay></video>
<button id="click-photo">Click Photo</button>
<canvas id="canvas" width="320" height="240"></canvas>
<div class="wrap">
<video id="video"></video>
<div class="overlay">
<img src="https://i.imgur.com/A9J4iWz.png" alt="">
</div>
</div>
<script>
let camera_button = document.querySelector("#start-camera");
let video = document.querySelector("#video");
let click_button = document.querySelector("#click-photo");
let canvas = document.querySelector("#canvas");
camera_button.addEventListener('click', async function () {
let stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false });
video.srcObject = stream;
});
click_button.addEventListener('click', function () {
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let image_data_url = canvas.toDataURL('image/jpeg');
// data url of the image
console.log(image_data_url);
});
</script>
</body>
</html>
.wrap {
position: relative;
}
video {
width: 320px;
height: 240px;
z-index: 1;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
z-index: 2;
text-align: center
}
img {
display: inline-block;
}

Google recaptcha style problem, solve with css or javascript?

I'm using recaptcha v.2 for my website, but for some reason, it brakes the layout because it won't size the space of the parent box (div).
Here's my code:
<script type="text/javascript">
var onloadCallback = function() {
grecaptcha.render('recaptcha', {
'sitekey' : 'mysitekey'
});
};
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer>
and html:
<div class="form-group">
<div id="recaptcha" required=""></div>
</div>
The form-group is already max-width: 100%; but for some reason, the recaptcha doesn't follow that rule:
Here's an example:
https://careercollege.sehc.com/vancouver/programs/hca-diploma-program/.
Any suggestion?
I do this sometimes:
#recaptcha {
overflow: hidden;
border-right: solid 1px lightgray;
}

bootstrap-vue change the position of <b-modal>

By default <b-modal> shows on top of the page. When attribute centered is added to the tag. It is centered.
However, I would like to show the modal with a certain amount of gap under the top of the page.
The Modal is shown when the home page is opened.
AppModal.vue
<template>
<b-modal ref="thisModalRef" :modal-class="my-modal" size="lg" hide-header hide-footer no-close-on-backdrop hide-header-close>
//...
</b-modal>
</template>
<script>
export default {
data () {
return {
mymodal: ['mymodal']
}
},
methods: {
hideModal () {
this.$refs.thisModalRef.hide()
},
showModal () {
this.$refs.thisModalRef.show()
}
}
}
</script>
<style scoped>
.mymodal > div {
position: absolute;
top: 300px;
right: 100px;
background-color: yellow;
}
</style>
AppHome.vue
<template>
<div>
// omitted
<AppModal ref="modalRef"></AppModal>
</div>
</template>
<script>
import AppModal from './AppModal'
export default {
components: {
AppModal
},
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
methods: {
showModal: function () {
this.$refs.modalRef.showModal()
}
},
mounted () {
this.showModal()
}
}
</script>
<style scoped>
// ommitted
</style>
html source related to modal
<div id="__BVID__16___BV_modal_outer_">
<div id="__BVID__16" role="dialog" class="modal fade show d-block mymodal" style="padding-right: 15px;">
<div class="modal-dialog modal-lg">
<div tabindex="-1" role="document" aria-describedby="__BVID__16___BV_modal_body_" class="modal-content">
<!---->
<div id="__BVID__16___BV_modal_body_" class="modal-body">
// ommitted
</div>
<!---->
</div>
</div>
</div>
<div id="__BVID__16___BV_modal_backdrop_" class="modal-backdrop fade show"></div>
</div>
As you can see, mymodal class is correctly applied. But the div .modal-dialog does not have the css properties I give it.
the real css properties found in dev tools
.modal-dialog {
position: relative;
width: auto;
margin: 0.5rem;
pointer-events: none;
}
I tried adding a custom class to <b-modal> and style it. Nothing worked.
Please help.
If you want to put the modal into the specific position, below is my solutuon:
add specific class to <b-modal> by its props=modal-class
then add your styles into myclass > div
You can look into the github (line#:176), Bootstrap-vue will place one div.modal-content(including header/body/foot) into one div with class="modal-dialog" which is the direct child of root.
That is why above solution use the css selector = .myclass > div.
If you look into the dom tree: the structure of one bootstrap-vue modal will be:
one root div (myclass will be added into here) -> one div with modal-dialog -> one div with modal-content -> header/body/footer
Below is one sample: (I put different background-color for modal-dialog, modal-content.)
app = new Vue({ //not vue, it is Vue
el: "#app",
data: {
myclass: ['myclass']
},
methods: {
showModal: function(){
this.$refs.myModalRef.show()
}
}
})
.myclass > div {
position:absolute !important;
top: -10px !important;
left: -10px !important;
background-color:yellow !important;
}
.myclass > .modal-dialog > .modal-content {
background-color:red !important;
}
<!-- Add this to <head> -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css"/>
<!-- Add this after vue.js -->
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<script src="//unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-button #click="showModal">
Open Modal
</b-button>
<b-modal ref="myModalRef" :modal-class="myclass" size="lg">
<h2>Test</h2>
</b-modal>
</div>
I use
<b-modal
body-class="modalcart"
ref="addToCart"
id="addToCarModal"
hide-footer
hide-header
>
<b-container class="text-center modal-product-content">
<img class="modal-image" src="~/assets/images/add-to-cart.png" alt=""/>
and:
<style lang="scss" scoped>
/deep/ .modalcart {
font-family: 'poppins-bold';
/deep/ .modal-product-content {
padding: 3rem;
margin: 0 auto !important;
/deep/ .modal-image {
height: 150px;
margin-bottom: 2rem;
}
}
...
}
</style>
and work! thanks
Keep in mind that not work without body-class and /deep/
I use node-sass, vue 3, vue-loader 15
Maybe you could try with something like margin-top: 100px.
I think it's because the #media breakpoint of Bootstrap. Then, in <style> you just override it.
#media (min-width: 576px) {
.modal-dialog {
margin: .5rem auto;
}
}

Dart Language: how to get an image from another element?

I have two table rows at an HTML file: the first one is empty and the other one has a background image. I would like to know if there's any way to get that background image and transfer it to the first row when it gets clicked.
(Right now I'm setting the background image at the CSS code, but I think that I'll have to move it to the HTML in order for it to work. Or maybe not?)
Thanks for the help!
index.html
<head>
<style>
div {
width: 50px;
height: 50px;
border: 1px solid red;
}
#id1 {
background-image: url('action-icons.png');
}
</style>
</head>
<body>
<div id='id1'>xxx</div>
<div id='id2'>yyy</div>
</body>
index.dart
import 'dart:html';
main () {
querySelector('#id2').onClick.listen((e) {
var div1 = querySelector('#id1');
var div2 = querySelector('#id2');
div2.style.backgroundImage = div1.getComputedStyle().backgroundImage;
div1.style.backgroundImage = 'none';
});
}

How to use the new affix plugin in twitter's bootstrap 2.1.0?

The bootstrap documentation on that topic is a little confusing to me. I want to achieve similar behaviour like in the docs with the affix navbar: The navbar is below a paragraph / page heading, and upon scrolling down it should first scroll along until reaching the top of the page, and then stick there fixed for further scrolldowns.
As jsFiddle does not work with the navbar concept, I've set up a separate page for usage as a minimal example: http://i08fs1.ira.uka.de/~s_drr/navbar.html
I use this as my navbar:
<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
<div class="navbar-inner">
<div class="container">
<div class="span12">
<a class="brand" href="#">My Brand</a>
This is my navbar.
</div>
</div> <!-- container -->
</div> <!-- navbar-inner -->
</div> <!-- navbar -->
I thinkg i would want data-offset-top to be of value 0 (since the bar should "stick" to the very top" but with 50 there is at least some effect watchable.
If also put the javascript code in place:
<script>
$(document).ready (function (){
$(".navbar").affix ();
});
</script>
Any help appreciated.
I was having a similar problem, and I believe I found an improved solution.
Don't bother specifying data-offset-top in your HTML. Instead, specify it when you call .affix():
$('#nav').affix({
offset: { top: $('#nav').offset().top }
});​
The advantage here is that you can change the layout of your site without needing to update the data-offset-top attribute. Since this uses the actual computed position of the element, it also prevents inconsistencies with browsers that render the element at a slightly different position.
You will still need to clamp the element to the top with CSS. Furthermore, I had to set width: 100% on the nav element since .nav elements with position: fixed misbehave for some reason:
#nav.affix {
position: fixed;
top: 0px;
width: 100%;
}
One last thing: When an affixed element becomes fixed, its element no longer takes up space on the page, resulting in the elements below it to "jump". To prevent this ugliness, I wrap the navbar in a div whose height I set to be equal to the navbar at runtime:
<div id="nav-wrapper">
<div id="nav" class="navbar">
<!-- ... -->
</div>
</div>
.
$('#nav-wrapper').height($("#nav").height());
Here's the obligatory jsFiddle to see it in action.
Just implemented this for the first time, and here's what I've found.
The data-offset-top value is the amount of pixels that you must scroll in order for the affixing effect to take place. In your case, once 50px is scrolled, the class on your item is changed from .affix-top to .affix. You'd probably want to set data-offset-top to about 130px in your use case.
Once this class change occurs, you must position your element in css by styling the positioning for class .affix. Bootstrap 2.1 already defines .affix as position: fixed; so all you need to do is add your own position values.
Example:
.affix {
position: fixed;
top: 20px;
left: 0px;
}
To fix this very issue I have modified the affix plugin to emit a jQuery event when an object is affixed or unaffixed.
Here is the pull request: https://github.com/twitter/bootstrap/pull/4712
And the code: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js
And then do this to attach the navbar:
<script type="text/javascript">
$(function(){
$('#navbar').on('affixed', function () {
$('#navbar').addClass('navbar-fixed-top')
});
$('#navbar').on('unaffixed', function () {
$('#navbar').removeClass('navbar-fixed-top')
});
});
</script>
You need to remove .affix() from your script.
Bootstrap gives the option of accomplishing things either via data-attributes or straight JavaScript most of the time.
I've got this from the twitterbootstrap's source code and it's working pretty well:
HTML:
<div class="row">
<div class="span3 bs-docs-sidebar">
<ul id="navbar" class="nav nav-list bs-docs-sidenav">
...
</ul>
</div>
</div>
CSS:
.bs-docs-sidenav {
max-height: 340px;
overflow-y: scroll;
}
.affix {
position: fixed;
top: 50px;
width: 240px;
}
JS:
$(document).ready(function(){
var $window = $(window);
setTimeout(function () {
$('.bs-docs-sidenav').affix({
offset: {
top: function (){
return $window.width() <= 980 ? 290 : 210
}
}
})
}, 100);
});
You just need to remove the script. Here is my example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>
<style>
#content {
width: 800px;
height: 2000px;
background: #f5f5f5;
margin: 0 auto;
}
.menu {
background: #ccc;
width: 200px;
height: 400px;
float: left;
}
.affix {
position: fixed;
top: 20px;
left: auto;
right: auto;
}
</style>
</head>
<body>
<div id="content">
<div style="height: 200px"></div>
<div class="affix-top" data-spy="affix" data-offset-top="180">
<div class="menu">AFFIX BAR</div>
</div>
</div>
</body>
</html>
Thanks to namuol and Dave Kiss for the solution.
In my case I had a tiny problem with navbar height and width when I used afflix and collapse plugins together. The problem with width can be easily solved inheriting it from parent element (container in my case). Also I could manage to make it collapsing smoothly with a bit of javascript (coffeescript actually). The trick is to set wrapper height to auto before collapse toggle occurs and fix it back after.
Markup (haml):
#wrapper
#navbar.navbar
.navbar-inner
%a.btn.btn-navbar.btn-collapse
%span.icon-bar
%span.icon-bar
%span.icon-bar
#menu.nav-collapse
-# Menu goes here
CSS:
#wrapper {
width: inherit;
}
#navbar {
&.affix {
top: 0;
width: inherit;
}
}
Coffeescript:
class Navigation
#initialize: ->
#navbar = $('#navbar')
#menu = $('#menu')
#wrapper = $('#wrapper')
#navbar.affix({offset: #navbar.position()})
#adjustWrapperHeight(#navbar.height())
#navbar.find('a.btn-collapse').on 'click', () => #collapse()
#menu.on 'shown', () => #adjustWrapperHeight(#navbar.height())
#menu.on 'hidden', () => #adjustWrapperHeight(#navbar.height())
#collapse: ->
#adjustWrapperHeight("auto")
#menu.collapse('toggle')
#adjustWrapperHeight: (height) ->
#wrapper.css("height", height)
$ ->
Navigation.initialize()
My solution for attach the navbar :
function affixnolag(){
$navbar = $('#navbar');
if($navbar.length < 1)
return false;
h_obj = $navbar.height();
$navbar
.on('affixed', function(){
$navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
})
.on('unaffixed', function(){
if($('#nvfix_tmp').length > 0)
$('#nvfix_tmp').remove();
});
}
Similar to the accepted answer, you can also do something like the following to do everything in one go:
$('#nav').affix({
offset: { top: $('#nav').offset().top }
}).wrap(function() {
return $('<div></div>', {
height: $(this).outerHeight()
});
});​
This not only invokes the affix plugin, but will also wrap the affixed element in a div which will maintian the original height of the navbar.

Resources