How do I fetch CSS Coverage data using chrome dev protocol? - css

I am working on creating a simple java class which would give me used & unused css on any given page.
public class coverage {
static String str;
public static void main(String[] args) throws JSONException {
String url = "https://www.amazon.com";
Launcher launcher = new Launcher();
try (SessionFactory factory = launcher.launch();
Session session = factory.create()) {
Command command = session.getCommand();
DOM dom = command.getDOM();
CSS css = command.getCSS();
session.navigate(url);
dom.enable();
css.enable();
HashMap<String, List<String>> hm = new HashMap<String, List<String>>();
HashMap<String, String> hmUsedCSS = new HashMap<String, String>();
css.startRuleUsageTracking();
List<RuleUsage> list = css.stopRuleUsageTracking();
for (RuleUsage coverage : list) {
if (!hm.containsKey(coverage.getStyleSheetId())) {
hm.put(coverage.getStyleSheetId(),
css.collectClassNames(coverage.getStyleSheetId()));
}
if (!coverage.isUsed()) {
String existingContent = hmUsedCSS.get(coverage
.getStyleSheetId());
String extraContent = css.getStyleSheetText(coverage
.getStyleSheetId());
hmUsedCSS.put(coverage.getStyleSheetId(),
existingContent == null ? extraContent
: existingContent + extraContent);
}
}
for (String name : hm.keySet()) {
List<String> value = hm.get(name);
System.out.println("Total " + name + "=>" + value);
}
for (String name : hmUsedCSS.keySet()) {
List<String> value = hm.get(name);
System.out.println("Used CSS " + name + "=>" + value);
}
}
}
}
As per official documentation, 'stopRuleUsageTracking' would tell us whether a particular CSS is being used or not by setting 'used' boolean in RuleUsage , but it is returning all the CSS available on the page with 'used' set to true.I figured out that the answer lies in startoffset & endoffset values as they tell us the positioning of used CSS.But I don't know how to convert these values into meaningful result of Used & Unused CSS ? Can someone help me out here?

As I pointed out in the question , the key was to fetch coverage data as per start & end offset values.I was able to write logic to do the same & got the required list of used & Unused CSS.

Related

Creating RocksDB SST file in Java for bulk loading

I am new to RocksDB abd trying to create a SST file in Java for bulk loading. Eventual usecase is to create this in Apache Spark.
I am using rocksdbjni 6.3.6 in Ubuntu 18.04.03
I am keep getting this error,
org.rocksdb.RocksDBException: Keys must be added in order
at org.rocksdb.SstFileWriter.put(Native Method)
at org.rocksdb.SstFileWriter.put(SstFileWriter.java:104)
at CreateSSTFile.main(CreateSSTFile.java:34)
The sample code is
public static void main(String[] args) throws RocksDBException {
RocksDB.loadLibrary();
final Random random = new Random();
final EnvOptions envOptions = new EnvOptions();
final StringAppendOperator stringAppendOperator = new StringAppendOperator();
Options options1 = new Options();
SstFileWriter fw = null;
ComparatorOptions comparatorOptions = new ComparatorOptions();
try {
options1 = options1
.setCreateIfMissing(true)
.setEnv(Env.getDefault())
.setComparator(new BytewiseComparator(comparatorOptions));
fw = new SstFileWriter(envOptions, options1);
fw.open("/tmp/db/sst_upload_01");
for (int index = 0; index < 1000; index++) {
Slice keySlice = new Slice(("Key" + "_" + index).getBytes());
Slice valueSlice = new Slice(("Value_" + index + "_" + random.nextLong()).getBytes());
fw.put(keySlice, valueSlice);
}
fw.finish();
} catch (RocksDBException ex) {
ex.printStackTrace();
} finally {
stringAppendOperator.close();
envOptions.close();
options1.close();
if (fw != null) {
fw.close();
}
}
}
If the loop index is less than 10 the file is created successfully and I was able to ingest that into rocks db.
Thanks in advance.
I think I found the problem with the code.
The keys must be in order for the SST. The way I do the looping and using String lexicographical comparison for ordering, produces incorrect ordering. Like comparing "10" and "9" would break the order. Instead of that, if I sort all the keys before inserting into SST file it works.
Map<String, String> data = new HashMap<>();
for (int index = 0; index < 1000; index++) {
data.put("Key-" + random.nextLong(), "Value-" + random.nextDouble());
}
List<String> keys = new ArrayList<String>(data.keySet());
Collections.sort(keys);
for (String key : keys) {
Slice keySlice = new Slice(key);
Slice valueSlice = new Slice(data.get(key));
fw.put(keySlice, valueSlice);
}
When I tried with integer keys I found the issue.
The keys in sstfile should be in increasing order.
so you can start from index=10 it will work.
In fact ,you can create Comparator extends DirectComparator to avoid sorted.
class MyComparator extends DirectComparator {
public MyComparator(ComparatorOptions copt) {
super(copt);
}
#Override
public String name() {
return "MyComparator";
}
#Override
public int compare(DirectSlice a, DirectSlice b) {
// always true
return 1;
}
}
}
then set option
options1.setComparator(new MyComparator(comparatorOptions));

How to select multiple lines using java Selenium automation testing?

I tried to select multiple lines using selenium automation like below.
this.selectLineInTable(Locator.LOCATOR_LIST, "name", t1.getName()).
this.selectLineInTable(Locator.LOCATOR_LIST,"name",t2.getName()));
but its not working. Can anyone help me how to solve this issue?
try something like below:
Actions act = new Actions(driver);
act.keyDown(Keys.CONTROL).moveToElement(driver.findElement(By.xpath("first element to select"))).click().build().perform();
act.moveToElement(driver.findElement(By.xpath("second element to select"))).click().release().build().perform();
Actions act = new Actions(driver);
String m1 = this.selectLineInTable(Constant.LOCATOR_LIST_MOFULL, "name",psv.getName());//1st element
String m2=this.selectLineInTable(Constant.LOCATOR_LIST_MOFULL, "name",psTest.getName());// 2nd element
act.keyDown(Keys.CONTROL).moveToElement(driver.findElement(By.name(m1))).click().build().perform();
act.moveToElement(driver.findElement(By.name(m2))).click().release().build().perform();
protected String selectLineInTable(String scLocatorBody, String key, String value) throws Exception {
String scLocatorLine = this.findLineInTable(scLocatorBody, key, value);
if (scLocatorLine == null) {
// No line for key / value
this.logError("The row [" + key + "=" + value + "] does not exist", null);
} else {
// Click on the line
StringBuffer lRow = new StringBuffer();
lRow.append(scLocatorLine).append("col[fieldName=").append(key).append("]/");
this.clickOnElement(lRow.toString());
sleep(500);
}
return scLocatorLine;
}
Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"name","selector":"scLocator=//ListGrid[ID=\"ssr_grid\"]/body/row[0]/"}

replace DescriptionAttr with Dictionary or smth

I have a enum that's contain Description Attribute(for audit):
public enum ActivityType
{
[NotExist("Not Assign")]
[Description("Change Level")]
LevelChanged,
[NotExist("Not Assign")]
[Description("Change Skill Level")]
SkillLevelChanged
}
And all had been great until i needed to put Desription in Resource files(attribute didn't support them), so i need Dictionary or something like this.The question is: How implement this feature without big changing in all another logic?Something like this:
private static readonly Dictionary<ActivityType, String> ActivityDescription = new Dictionary<ActivityType, String>()
{
{ActivityType.LevelChanged, "Change"},
{ActivityType.SkillLevelChanged, "SkillChange"}
}
The solution that requires the minimal amount of code change for you would be to alter your descriptions to be the resource keys in your resource file. Then you could read these dynamically by doing something like:
[Description("Change_Level")]
Then your resource key/value would be:
Change_Level Change Level
And to read it you can do:
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute attribute = value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.SingleOrDefault() as DescriptionAttribute;
if (attribute != null)
{
var resManager = new ResourceManager(typeof(MyResources));
return resManager.GetString(attribute.Description);
}
else
{
return value.ToString();
}
If however you're wanting a nicer solution with the option to pass in the resource file, you can hijack the Display attribute:
[Display(ResourceType = typeof(MyResources), Name = "Change_Level")]
Then you can do:
FieldInfo fi = value.GetType().GetField(value.ToString());
DisplayAttribute attribute = value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(DisplayAttribute), false)
.SingleOrDefault() as DisplayAttribute;
if (attribute != null)
{
var resManager = new ResourceManager(attribute.ResourceType);
return resManager.GetString(attribute.Name);
}
else
{
return value.ToString();
}

Elegant way to bind html radio buttons <=> Java enums <=> mysql enums in Play?

The Goal is to have a list of options (that a user can chose through radio buttons) in one place(for eg: a yaml config file). No other place should have this list hard-coded
I've done something similar to create select elements, and I think enums worked just fine. Doing radio buttons should be very similar. I've set it up so that the labels can be defined in the messages file. I'm going to try to excerpt the relevant portions from my larger auto-form-generation code (using FastTags) the best I can. It's a bit heavy for this one case but it makes sense in the larger system.
I use the tag like #{form.selector 'order.status' /}, which looks find the variable named order in the template, sees that status is declared as public Status status, and then goes to find all the values of the Status enum and generate options for them in the select element.
First, I use a FieldContext object which just contains a bunch of info that's used by the other code to determine what to generate along with some utility methods:
public class FieldContext {
public final Map<?,?> args;
public final ExecutableTemplate template;
public final int fromLine;
public Class clazz = null;
public Field field = null;
public Object object = null;
public Object value = null;
private Map<String,String> attrs = new HashMap<String,String>();
private Map<String,Boolean> printed = new HashMap<String,Boolean>();
private List<Option> options;
...
Then I have this in another helper class (its info gets added to the FieldContext):
public List<Option> determineOptions(FieldContext context) {
List<Option> options = new ArrayList<Option>();
if (context.field.getType().isEnum()) {
for (Object option : context.field.getType().getEnumConstants()) {
options.add(new Option(option.toString(), Message.get(option.toString())));
}
}
return options;
}
then the tag declaration is
public static void _selector(Map<?,?> args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) {
String field_name = args.get("arg").toString();
TagContext.current().data.put("name", field_name);
SelectHelper helper = HelperFactory.getHelper(SelectHelper.class);
try {
FieldContext context = new FieldContext(field_name, args, template, fromLine);
helper.autoconfigure(context);
TagContext.current().data.put("selected", helper.determineValue(context));
out.print("<div class=\"formutil-field formutil-selector\">");
out.print("<label for=\"" + context.getAttr("id") + "\">");
out.print(helper.findOrCreateLabel(context));
out.print("</label>");
out.print("<select");
context.printAttribute(out, "id", "name");
out.print(">");
if (context.hasOptions()) {
for (Option option : context.getOptions()) {
out.print("<option value=\"" + option.value + "\">" + option.label + "</option>");
}
}
out.print("</select>");
context.printErrorIfPresent(out);
context.printValidationHints(out);
out.println("</div>");
}
...
}

AS3/Flex 4: Most Practical Way To Find Nested Children

I'm sort of jumping in headfirst to some Flex/AIR stuff. I have a pretty solid background with AS3, but given the inherent hierarchal complexity of Flex (compared to regular Flash), I'm running into an issue.
Let's assume that you have an app where pretty much everything is event driven (common). Accessing elements in the near vicinity of the event target, or the event target itself, is trivial. I'm trying to find, however, the most practical (read: best, most efficient) way to find children that are far removed from the current context.
I know there are functions like getChildAt() and getChildByName(), but that assumes a parent context; what if the element (Flex) you're looking for is several parents up, in a sibling, and then several children down? We take for granted things like jQuery that do this easily, but obviously we don't have that luxury in AS3.
Are any of the following valid? Is there a better way?
Iterate through parents and parents' parents until you find a stop point, find the sibling, and iterate through children and their children until you find your target;
Keep key objects in a global object store (sic) and reference them as necessary (yech)
Use specific dot notation to reach the target, including elements (like skins and their containers - yech again)
Any thoughts would be appreciated.
Edit:
To clarify, let's take an empty Flex 4 AIR app. We have WindowedApplication as the root, obviously, and let's add two SkinnableContainer children with IDs navContainer and mainContainer, respectively. Both have custom skins. Within mainContainer, we have another SkinnableContainer with a vertical layout and ID mainContent, and as one of its children, it has an object (any will do - a spark BorderContainer, maybe) with the ID animatedBox, for example. Within the navContainer, we have a spark Button, which has a listener bound for MouseEvent.CLICK. Within that function, we are going to want to access animatedBox (nativeWindow.mainContainer.mainContent.animatedBox) and animate it to change, say, it's width.
The goal is to access that distant DisplayObject (animatedBox) in a way that is as unobtrusive and efficient as possible, while still conforming to Flex standards that I clearly have yet to possess. :)
in my implementation it is easy to do (however it's in pure AS3):
in display object which handles the click:
private function onClick(e:MouseEvent):void{
Radio.broadcast(new CustomEvent(id, ..params));
}
in animatedBox:
Radio.addListener(id, new Reciever(uid, animate));
private function animate(e:CustomEvent) {
//needed code and access of CustomEvent props you pass
}
upd:
package lazylib.broadcast
{
/**
* ...
* #author www0z0k
*/
public class Reciever
{
private var id: String;
private var toRun: Function;
/*#param nm - unique listener id - required
*#param fn - event handler function - required*/
public function Reciever(nm:String, fn:Function)
{
id = nm;
toRun = fn;
}
public function onEvent(e:* = null):String {
if (e == null) { return id; }
toRun(e);
return id;
}
public function get ID():String { return id; }
}
}
and
package lazylib.broadcast
{
import flash.events.Event;
import flash.events.EventDispatcher;
/**
* ...
* #author www0z0k
*/
public final class Radio extends EventDispatcher
{
private static var listeners: Object = new Object();
private static var archive: Array = new Array();
private static var forSlowpokes: Object = new Object();
public static function get ForSlowpokes():Object { return forSlowpokes; }
public static function addListener(type: String , listener: Reciever):Boolean {
listeners['anchor'] = null;
if (!listeners[type]) {
var o: Object = new Object();
listeners[type] = o;
}
if (!listeners[type][listener.ID]) {
listeners[type][listener.ID] = listener;
return true;
}else {
return false;
}
}
public static function broadcast(evt: * , singleUse:Boolean = false):void {
var type:String = (evt as Event).type;
if (listeners[type]) {
var returned: Array = new Array();
for (var i: String in listeners[type]) {
if(listeners[type][i]){
var fnRetVal: String = listeners[type][i].onEvent(evt);
returned.push(fnRetVal);
}else{
//trace("no listener for id = " + i + ' , type = ' + type);
}
}
}else {
//trace("nobody's interested in : \"" + type + "\"");
}
if (singleUse) {
forSlowpokes[type] = 'you missed it realtime';
delete listeners[type];
}
}
public static function clearDeadFuncs(namez:Object):void {
for (var a:String in namez) {
if (a != 'anchor') {
killListener(a, namez[a]);
}
}
}
public static function killListener(type: String , id: String):Boolean {
if (!listeners[type]) {
//trace("there are no listeners for event : " + "\"" + type + "\"");
return false;
}else {
if (!listeners[type][id]) {
//trace("there is no \"" + id + "\" listener for event : " + "\"" + type + "\"");
return false;
}else {
listeners[type][id] = null;
//trace("removed listener \"" + id + "\" for event : " + "\"" + type + "\"");
var evt2kill: Number = 0;
for (var str: String in listeners[type]) {
if (listeners[type][str]) {
evt2kill++;
}
}
if (evt2kill == 0) {
delete listeners[type];
//trace("no more listeners for event : " + "\"" + type + "\"");
return true;
}
return true;
}
}
}
}
}
delivered as is ;)
We take for granted things like jQuery that do this easily, but obviously we don't have that luxury in AS3.
well there is this: http://tech.nitoyon.com/blog/2008/01/as3query_alpha.html
I asked myself this question also a lot of times. Still haven't figured out an ultimate solution to the problem. Iterating through parents and parents is definately a way but has to be taken with caution, cause relations might change in your application during runtime. I wrote a simple method a few days ago that lets you iterate through all parents of a given object. Definitely not an elegant solution but it works so far. the SWIZ framework also offers good methods to facilitate the communication between objects via code injection and Event mediation. Maybe worth a look...

Resources