I'm starting with cypress and need to compare 2 different environments.
I did a script, but is not working properly.
My goal is:
1 - search for a specific selector value at 2 different environments.
2 - get it's value (in both env) , and then compare it if equal.
The below comparision work, but seems very poor code and it stop in first error assert and can't query reference selector, just text.
Any help is appreciated.
describe('Testing Page', function() {
//urls i need to test
var relative_urls = [
'/products/test1',
'/products/test2',
]
relative_urls.forEach((url) => {
//each url is compared here...
var productInfo = [];
//here goes the environments URL.
var testURL = 'https://www.myurl.com' + url;
var referenceURL = 'http://test.myurl.com' + url;
it('Comparing data from url:' + url, function() {
cy.visit(testURL)
//get data from selector and add it to array
cy.get('body').find(".myselector h1").should(($input) => {
productInfo.push($input.val())
})
cy.get('body').find(".myselector h2").should(($input) => {
productInfo.push($input.val())
})
//requesting second url
cy.request(referenceURL)
.its('body').should( ($input) => {
for (var j=0;j<productInfo.length;j++) {
//expect works, but compares to all site, and i need to search in a specific selector.
//Also, when it gets the first error, it stops and do not search all elements of array
expect($input.includes(productInfo[j]), 'Notice: ' + productInfo[j]).to.be.true
}
}
})
})
})
})
From reading the documentation, cy.request is really making a plain HTTP request without doing any parsing, which means you basically have to parse the body of the response yourself. cy.visit will actually get the DOM elements so you can use Cypress's query syntax to navigate the page.
I think once you have the element values from the first page you should just do cy.visit again and parse the second page.
EDIT: Apparently you can't use cy.visit cross-domain. In that case, maybe you could try parsing the response body into a DOM node like this:
var el = document.createElement( 'html' );
el.innerHTML = request.body // you can get the request object from cy.request;
Then use el.querySelector to navigate the DOM tree using CSS syntax.
Related
As title, in this post I already know how to retrieve all-suggestion-accepted content of a document. Now I also want to retrieve the "style suggestion" of the content of the document. I've referred to the second half part of this guideline, but still have no clue about it. Below is the snippet I have as yet.
function get_all_suggestion_accepted()
{
var doc_id = 'My doc ID';
SUGGEST_MODE = 'PREVIEW_SUGGESTIONS_ACCEPTED'
suggestions = Docs.Documents.get(doc_id, {
'suggestionsViewMode': SUGGEST_MODE,
"textStyleSuggestionState": { "underlineSuggested": true, }
});
var new_content = '';
suggestions.body.content.forEach(obj => {
if(obj.paragraph)
obj.paragraph.elements.forEach(element => {
new_content += element.textRun.content;
});
});
console.log(new_content);
}
Currently, accepting/rejecting suggestions via Google Docs API is not possible.
To retrieve the style suggestion, you need to access the textRun of each paragraph element and check if suggestedTextStyleChanges exists.
Example:
Code:
function myFunction() {
var suggestions = Docs.Documents.get("doc id");
suggestions.body.content.forEach(obj => {
if(obj.paragraph)
obj.paragraph.elements.forEach(element => {
if(element.textRun.suggestedTextStyleChanges){
Logger.log(element.textRun.content);
Logger.log(element.textRun.suggestedTextStyleChanges);
}
});
});
}
Output:
Edit
In your code, you added "textStyleSuggestionState": { "underlineSuggested": true, }, but Docs.get method only accepts suggestionsViewMode as Query Parameter and the values you can input are:
DEFAULT_FOR_CURRENT_ACCESS - The SuggestionsViewMode applied to the
returned document depends on the user's current access level. If the
user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is applied.
Otherwise, SUGGESTIONS_INLINE is applied. This is the default
suggestions view mode.
SUGGESTIONS_INLINE The returned document has suggestions inline.
Suggested changes will be differentiated from base content within the
document.
Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.
PREVIEW_SUGGESTIONS_ACCEPTED The returned document is a preview with
all suggested changes accepted.
Requests to retrieve a document using this mode will return a 403
error if the user does not have permission to view suggested changes.
PREVIEW_WITHOUT_SUGGESTIONS The returned document is a preview with
all suggested changes rejected if there are any suggestions in the
document.
The correct way to find all the underlineSuggested: true is by traversing it in the Response body and use SUGGESTIONS_INLINE as suggestionsViewMode.
Example:
Document:
This code will print the string that has underline suggestion:
function get_all_suggestion_accepted() {
var suggestions = Docs.Documents.get("11Tx4uvv5yN_TplT4TIUyEWTZ6bUMTGaensYT20EZ4r0");
suggestions.body.content.forEach(obj => {
if(obj.paragraph)
obj.paragraph.elements.forEach(element => {
if(element.textRun.suggestedTextStyleChanges){
var obj = JSON.parse(JSON.stringify(element.textRun.suggestedTextStyleChanges));
if(obj[Object.keys(obj)[0]].textStyleSuggestionState.underlineSuggested){
Logger.log(element.textRun.content);
}
}
});
});
}
Output:
Note: If you want to view all the suggestions, you have to use SUGGESTIONS_INLINE in the textStyleSuggestionState query parameter or remove it as SUGGESTIONS_INLINE is the default view if you have access to the document. Also, when you use PREVIEW_SUGGESTIONS_ACCEPTED you won't see any suggestions in the object as it returns a preview of the document with all the suggestions accepted.
Further Reading
SuggestedTextStyle
Javascript Object
HTTP Request methods
Hoping you can help. I think I'm nearly there but my code has a slight error in it. I'm trying to set a cookie which sets the cookie value based on a section of the page url.
For example my cookie name is "model" and my cookie value is populated based on the url
https://www.website.co.uk/cars/100sr/
in the example above the cookie value should be set as 100sr
However, I've just noticed an error, where if the customer visits my website with a query string on the url, it's setting the cookie value to the query string content not the 100sr
e.g.
https://www.website.co.uk/cars/100sr/?testing
the url above using my current code would set the cookie as ?testing when I want it to still be set as 100sr. I'm guessing my code is taking the content after the LAST / is there perhaps a way to specify to take the content after the 2nd / instead?
Code below
<script>$("#carbtn").bind("click", function() {
const strings = window.location.href.split("/").filter(str => !!str);
document.cookie=`model=${strings[strings.length - 1]};path=/;`
});</script>
If you use the pathname instead of the href, you'll be able to retrieve the portion of the URL without the query string. For example, on the URL:
Split URL to set cookie using Javascript
Using window.location.pathname returns:
"/questions/67402851/split-url-to-set-cookie-using-javascript"
So do:
$("#carbtn").bind("click", function() {
const strings = window.location.pathname.split("/").filter(str => !!str);
document.cookie = `model=${strings[strings.length - 1]};path=/;`
});
<script>$("#carbtn").bind("click", function() {
const strings = window.location.href.split("/").filter(str => !!str);
document.cookie=`model=${strings[strings.length - 1]};path=/;`
});</script>
This code gets the last element on the split of "/", so "/my/path/" gets the empty string after "path/[HERE]", you might need to dig into the awful (or wonderful) world of regexp for that
const lastItemOnURL = window.location.pathname.match(/[^\/]+\/?$/);
if (lastItemOnURL[0]) { document.cookie = `model=${lastItemOnURL[0].replace('/', '')};path=/;` }
Notice that window.location.pathname doesn't grab the eventual ?get=values in the URL so you probably need that too
I configured the extension tt_address in my page. I need to filter the address by its year. So I build a select box. I need to append some query parameter with its url to access in controller for implementing the filter.
The functionality is done successfully. But realurl is not working for this particular functionality.
main.js
function initYearFilter() {
var selectedItem = sessionStorage.getItem('year');
if (selectedItem !== null) {
$('.year-filter select').val(selectedItem);
}
$('.year-filter select').on('change', function () {
var loc = location.href.match(/.*people\/alumni\/+/)[0],
url;
if ($(this).val() == 'reset') {
url = loc + '?no_cache=1';
} else {
url = loc + '?ts_address[year]=' + $(this).val() + '&no_cache=1';
}
sessionStorage.setItem("year", $(".year-filter select").first().val());
window.location.href = url;
});
}
My realurl config
'postVarSets' => array(
'_DEFAULT' => array(
'year' => array(
array(
'GETvar' => 'ts_address[year]',
),
),
),
)
Don't let urls being generated manually in frontend, like you do in Javascript.
My advice here would be to generate the urls backend side and attach it to a option attribute (data-reset-url, data-url).
// maybe a foreach here
$GLOBALS['TSFE']->cObj->typolink_URL([
'parameter' => '_PAGEUID_',
'additionalParams' => '?ts_address[year]=' . $year, // suppose in foreach have year var
'no_cache' => true
]);
If you think ext:realurl is the culprit deactivate ext:realurl and look if it works then.
I think it still will not work, but you will see something in the url that should give you the neccessary hint.
You probably stumble over a security feature of TYPO3: cHash.
With a cHash URL parameter TYPO3 secures it's URLs against injection of unrelated parameters for a cached version of a page. If TYPO3 builds an URL it hashes all parameters and appends this hash to the url. If such a cHash is found in an URL the parameters are fetched from database and all current URL parameters are ignored. especially any additional parameters. So the cached page matches the given url.
If you use ext:realurl, this cHash parameter is hidden in a 'normal' URL path. If you add parameters, like in your javascript, they are removed as they are not encoded in the cHash, which is encoded in the speaking URL.
In your case the additional parameter would change the content of the page. This page could be cached if the additional parameter is included in a cHash.
Here you must help realurl to either build an URL without cHash, or build URLs which contain these individual cHashes:
You could build a menu of available years and also configure a pathsegment for the year. In this way you can get individual cHashes for each year. You need to change your javascript to add a path-segment instead of a parameter.
I have an api running that fetches all the file names in the directory and returns me an array inside an array. Currently, I am running it every second to check if a new file is added and if so... embed it to my div. The issue is that I have to empty my html every time and then re-embed the html. Is there a better way to do this? That way I only embed new filenames rather than all again.
setInterval(function(){
$.ajax({
url : 'getFiles',
success: function (data) {
$("#pics").html("");
console.log(data);
$.each(data, function (k, o) {
$.each(o, function (key, obj) {
$("#pics").append("<a href='#'>" + obj + "</a>");
});
});
}
});
}, 1000);
const images = [];
setInterval(function(){
$.ajax({
url : 'getFiles',
success: function (data) {
const fetchedImages = data.images;
if(images.length !== fetchedImages.length){ //They do not have the same elements
images = fetchedImages;
$("#pics").html("");
const domImages = fetchedImages.map(image => "<a href='#'>" + image + "</a>");
$("#pics").append(domImages.join(''));
}
}
});
}, 1000);
From our discussion i was able to create this solution.
Since you know that you only need a list of images, then you can just get it directly.
Then you can check if the images which are saved locally have the same amount of elements which you got from the server.
If they do not match, then it must mean that the list has been changed (a side-effect could be that someone changed the name of a file, then the length would be the same)
Now we just empty the #pics HTML, create a new array where each element is wrapped in an <a> tag
Lastly join just takes an array and converts it to a string. '' means that there shouldn't be any text between each element, so the string looks like this
"<a href='#'>image1.jpg</a><a href='#'>image2.jpg</a><a href='#'>image3.jpg</a>"
In your case, I will suggest to keep current implementation: clean all and generate the list by new received data. The reason is:
From performance view, clean all and regenerate it will faster than for each compare and check if duplicated => keep, remove old item or insert new item
the order of item can be easily kept as the received data. Won't be confused with the old item list.
The rule I suggest is: if the new list is totally the same, return without change directly. If the list has been changed, clean all and rebuild the list directly.
I have a webpage that takes a JSON via var url = myReport.json and displays information. The information it displays are server information that I am monitoring.
The server information monitors all applications running on the server, but it filters back ones that are named company_name_ and looks like this:
company_name_app1
company_name_app2
company_name_app3
company_name_app4
company_name_app5
On the html page, I want to remove the strings company_name_ so that the webpage will just display the following:
app1
app2
app3
app4
app5
Is there a way to remove a specified string match from the JSON entries so I can display it as wanted above?
EDIT:
<script>
//define a function that will fetch status and set icon URL
function setServerProcessesServer1761() {
var url = "Server1761.json";
var $svc = $("#Server1761-processes"); //get a reference to your <div>
$.getJSON(url, function(data) {
document.getElementById("Server1761-processes").innerHTML = data.processes.filter(s => s.Name.value.includes("company_name")).map(s => `<tr><td>${s.Name.value}</td> <td>${s.Status}</td></tr>`).join('\n');
$('#Server1761-processes').html(function (_, html) { return html.replace(/runn1ng/g,"<img src='smallgreen.png' />")});
$('#Server1761-processes').html(function (_, html) { return html.replace(/fai1ed/g,"<img src='smallred.png' />")});
}); // you will have to concatenate the entire services request line on line 130
}
//special jQuery syntax to run when document is ready (like onload but better)
$(function() {
setServerProcessesServer1761();
});
</script>
s.Name.value.replace("company_name_", "");
The above will replace company_name_part in the string with nothing. It uses the replace method from the String object.
String.replace(input (String, Regex), replace (String, Function))