dalekjs / dalek Goto Github PK
View Code? Open in Web Editor NEW[unmaintained] DalekJS Base framework
License: MIT License
[unmaintained] DalekJS Base framework
License: MIT License
Info:
DalekJS version 0.0.8 (CLI 0.0.4)
Operating System / version OS X 10.9.1
Browser and version PhantomJS 1.9.2
Currently Dalek does not update the :viewport value for a screenshot when .resize() is used.
When a test like this runs:
module.exports = {
'Page title is correct': function (test) {
test
.open('http://google.com')
.assert.title().is('Google', 'It has title')
.screenshot('first/:viewport_google.png')
.resize({width: 400, height: 400})
.screenshot('second/:viewport_google.png')
.done();
}
};
Dalek creates two screenshots that have different resolutions, but the :viewport labels them as having same resolution:
├── first
│ └── w1280_h1024_google.png
├── second
│ └── w1280_h1024_google.png
In order to be consistent with action names, the moveto in canary should be named moveTo.
Modules are supposed to be the only place a specific domain is handled. For this reason the config module manage have all the responsibilies involving reading config files, CLI arguments, ENV variables etc.
Currently this is done anywhere it's needed - mostly in Dalek itself. But modularization should make Dalek access config data only through the Config instance.
The command waitForElement isn't waiting until the element is available.
* DalekJS CLI Tools version : 0.0.2
* DalekJS local install : 0.0.1
* Operating system : windows 7
* Browser : Phantom, Chrome 30
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title der Seite</title>
</head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
window.setTimeout("activateButton()", 3000);
$('body').on('click', 'button', function() {
$('p').text('pressed Button');
});
});
function activateButton() {
$('button').css('display', 'block');
}
</script>
<h1>Dalek Bug waitForElement</h1>
<button style="display:none">Test</button>
<p></p>
</body>
</html>
After 3 seconds the button is displayed on the screen and you can click it. After Click you get a text in the p element.
If you place wait instead of waitForElement, then it works well, but you don't want to wait a special time, but be more generic.
The second part of the problem is more general. If you have a more complex site which a lot of elements and some are loaded or completed by ajax calls, than you need or more general solution instead of waitForElement something like JQuery $(document).ready() and it should be integrated in every assertion or action, because you don't want to write it in every second line.
module.exports = {
'Bug - waitForElement does not wait for the element.': function (test) {
test
.open('http://localhost/dalek/bug-waitForElement.html')
.waitForElement('button')
//.wait(3500)
.click('button')
.assert.text('p').is('pressed Button')
.done();
}
};
[http://dalekjs.com/docs/actions.html#meth-waitFor](waitFor documentation) shows the signatures waitFor(callback)
and waitFor(callback, string, number)
. if you want to specify a custom timeout (third argument) you have to pass something for second argument.
This suggests that you can only pass a single variable as an argument to waitFor()
- but the docs don't explain that. It might make sense to force the second argument to be an array (of arguments) - or replace everything but the callback itself by an options object, so optional values can be assigned by name and remain optional regardless of order.
When using Dalek with the browser plugin, if I have an element that is hidden on load, but gets displayed in response to an action on the page, Dalek does not see the newly visible element. For example, if I have a button that is hidden when the page loads, and I tell dalek to click a button whose click event causes the hidden button to become visible, assert.visible('#nowVisibleButton', 'Hidden Button now visible') fails and dalek does not see the button and cannot interact with it.
If I run dalek using phantomjs, the assertion fails and then it hangs if I tell dalek to click on that element.
Verions:
dalek: 0.0.8
OS: Mac OS X 10.9.1 x86_64
Browser: Chrome 33.0.1750.70
There is only a warning if you try to start an not existing test, but it should be an error and the test should not start in this case.
* DalekJS CLI Tools version : 0.0.2
* DalekJS local install : 0.0.1
* Operating system : windows 7
* Browser : Phantom
$ dalek not-existing-test
Running tests
Running Browser: PhantomJS
>> WARNING: Suite "dont-exists" does not exist. Skipping!
0/0 assertions passed. Elapsed Time: 7.08 sec
events.js:72
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED
at errnoException (net.js:901:11)
at Object.afterConnect [as oncomplete] (net.js:892:19)
trying to run some JavaScript in the browser hangs testing:
▶ WAITFOR
☁ [WEBDRIVER] webdriver: 200 POST /wd/hub/session/b9f2b2388b8853f45fac4a118835f05d/execute
☁ [WEBDRIVER] webdriver: {"sessionId":"b9f2b2388b8853f45fac4a118835f05d","status":13,"value":{"message":"unknown error: Cannot read property 'id' of undefined\n (Session info: chrome=31.0.1650.57)\n (Driver info: chromedriver=2.3,platform=Mac OS X 10.8.5 x86_64)"}}
The action should fail and the client's error message should be displayed in the test's console.
I would like to see XPath support to target elements that would be normally awkward (or sometime unfeasible) to target using standard CSS selectors.
Another possibility is to support JQuery-style selector extension such as which can then be used to offer a similar feature set to what XPath could offer (eg :contains()).
This might not be an easy one, but I'll ask anyway 😄
The scenario could be like this:
Imagine a site, where we have to test a lot of different things after for example having logged on first.
So, I imagine it would be better if we could somehow have a reusable setup function in which we first setup our complete login (with an assertion that it was successful, otherwise the whole test or tests should fail).
After the actual test, the reusable teardown function would then log the user out.
The setup and teardown functionality would probably itself be based on the testing functionality with a few extensions...
What do you think?
This results in dalek hanging:
test.sendkeys(...);
Notice the lower case k
.
It would probably be more helpful if it threw and error to make the mistake obvious to the developer.
The action wait() does not work and the error message in the shell is not understandable.
detailed description: https://github.com/dscherr/dalek-bugs
minimal example: https://github.com/dscherr/dalek-bugs/blob/master/test/bug-wait.js
Greetings
David
I have searched a lot for this issue, and i know that the Problem isn't dalekjs but maybe there is a solution for this.
Webdriver/the Browser gives 'wrong' rgba values.
For example if you write something like this.
'backgroundcolor is correct': function (test) { test.open(url) .assert.css('.backgroundStripe', 'background-color', 'rgba(98, 202, 217, 0.7)', 'backgroundStripe has right color') .done(); }
Instead of the expected (and in the stylesheet defined) value rgba(98, 202, 217, 0.7)
phantomjs returns rgba(98, 202, 217, 0.699219)
and chrome returns rgba(98, 202, 217, 0.701961)
I think the reason why this happend is:
http://stackoverflow.com/a/13754993/3233058
Maybe there is a simple solution for this, but i haven't found one.
Versions i used:
(at least on Windows anyhow)
Whenever I try to use log.message(), in any form, the test either stalls when it reaches that instruction, or the test "ends" immediately displaying the current number of assertions, but without exiting the process (I need to Ctrl+Break to exit it), or it's simply skipped without outputting any messages at all.
I haven't been able to get any of the log features working at all (message() and dom()).
The type action doesn't work as expected.
It looks like the following numeric characters are not sent to the browser : 0, 2, 7 and 9
The following test fails :
module.exports = {
'Google search': function (test) {
test.open('http://www.google.com')
.type('#gbqfq', '1234567890')
.click('#gbqfb')
.wait(1000)
.assert.title().is('1234567890 - Recherche Google', 'Title is OK')
.done();
}
};
Result for this test is :
Running Browser: Google Chrome
OS: Linux 3.2.0-51-generic x86_64
Browser Version: 30.0.1599.114
RUNNING TEST - "Google search"
▶ OPEN http://www.google.com
▶ TYPE #gbqfq
▶ CLICK #gbqfb
▶ WAIT 1000 ms
✘ TITLE
0 EXPECTED: 1234567890 - Recherche Google
0 FOUND: 134568 - Recherche Google
0 MESSAGE: Title is OK
✘ TEST - "Google search" FAILED
0/1 assertions passed. Elapsed Time: 4.02 sec
It would be pretty nice of Dalek could generate a name for the screenshot, based on the test it it executed in.
module.exports = {
'This is my awesome test': function( test ) {
test.screenshot( 'my/path/:name.png' )
}
would create a screenshot like my/path/this-is-my-awesome-test.png
.
Running Browser:
PhantomJS
An uncaughtException was found, the program will end.
[TypeError: Cannot call method 'fin' of undefined]
I tried to find where it was failing, but was unable to. Any ideas?
Any ideas?
Reverted windows node installation back to v0.10.24 for now.
Having an issue with the current stable version of DalekJS. I just did a clean install and tried to the run the quickstart 'Write your first test' test; But Dalek just exits after saying "Running tests"
I just tried to use the current Canary build
DalekJS CLI Tools Version: 0.0.2
DalekJS Canary local install: 0.0.1-2013-08-21-14-28-59
And got the following error: -
/projecta/core/node_modules/dalekjs-canary/node_modules/dalek-browser-phantomjs-canary/index.js:255
var browsers = this.config.get('browsers');
^
TypeError: Cannot call method 'get' of undefined
For organizing greater Tests with repetitive code, i need a possibility like macros, which you can integrate in different tests. I am not an advanced javascript developer, maybe there are existing possibilities for that. For example sometimes you need a special trick for your site for jQuery UI elements (select box?) and you want to solve this problem one time and use it over the whole tests. It would be very nice to write .selectbox-jqui('#address option[value="mister"]')
to select the special option or to handle birth dates in the same way by using .type-birth('1', '1', '1970')
(3 single input fields are grouped in this macro), but the main point is to define own commands.
The methods execute()
and waitFor()
(amongst other methods to come) accept functions to be executed in the browser context.
While one method may actually do something different, from a caller's perspective they look far too similar to allow them different signatures:
execute(func, arg1, arg2, arg3);
waitfor(func, [arg1, arg2, arg3], timeout)
Pick one style and stick with it.
Test:
module.exports = {
'TodoMVC - VanillaJS': function (test) {
test
.open('http://todomvc.com/vanilla-examples/vanillajs/')
.assert.numberOfElements('#todo-list li', 0, 'There should be no todos')
.done();
}
};
Command line output:
RUNNING TEST - "TodoMVC - VanillaJS"
▶ OPEN http://todomvc.com/vanilla-examples/vanillajs/
✔ 0 Assertions run
✔ TEST - "TodoMVC - VanillaJS" SUCCEEDED
The first value passed to a waitFor() callback is lost. The following example outputs "two, undefined" instead of "one, two".
{
test: function(test) {
test.waitFor(function(a, b) {
alert(a);
alert(b);
}, ['one', 'two']);
}
}
The docs for .screenshot()
suggest that the file suffix (".png") is added by Dalek - when in fact it isn't.
Just trying this out now and followed the instructions on http://dalekjs.com/pages/getStarted.html
Doesn't seem like dalek -v
is doing its job!
George@MacBook-Pro:~/Testing/dalek% dalek -v
Usage: dalek [test files] {OPTIONS}
Options:
--version, -v Shows the version of the dalek-cli & local dalek installation
--reporter, -r Reporter(s) you would like to invoke
--driver, -d Driver(s) you would like to invoke
--browser, -b Browser(s) you would like to invoke
--logLevel, -l Log level, controls the amount of information outputted to
the console (0 to 5)
--remote Starts a dalek host server for clients to connect to
--nocolors Disable colorized output in the console
--nosymbols Disable UTF-8 symbols in the console
--help, -h Show this message
[SyntaxError: Unexpected token /]
George@MacBook-Pro:~/Testing/dalek% dalek
>> ERROR: No test files given!
If I'm opening the same URLs (such as http://localhost:7497/tests/?full#5
) in multiple tests (via grunt-contrib-connect
, grunt-dalek
with chrome
option, see Gruntfile.js) it seems like Chrome is caching page states or just using the same page for tests with the same URL. I still haven't figure out proper test case, but something is definitely wrong. Here’s why:
I should also mention that those three tests also works fine in manual testing (if page is just loaded of course). And .reload()
right after .open(…)
doesn’t help.
Different tests shouldn’t affect each other results, right?
Right now it's possible to check the whole URL only which is less readable and doesn't work in unpredictable or static environment. It would be great to see more flexible URL matching.
When I pass relative URL like folder/index.html
it becomes file:///Users/…/folder/index.html
.
New relative()
method could match URL relative to folder where dalek is launched
.open('folder/index.html')
.assert.url.relative('folder/index.html')
New methogs could match specific URL parts
.open('folder/index.html?param=value#hash')
.assert.url.param('param', 'value')
.assert.url.hash('hash')
There are more URL parts that could be checked (domain levels, etc.), but I think these are essential.
Try to open an not existing URL freezes the test.
* DalekJS CLI Tools version : 0.0.2
* DalekJS local install : 0.0.1
* Operating system : windows 7
* Browser : Phantom
module.exports = {
'Try to open an not existing URL freezes the test': function (test) {
test
.open('http://not-existing-url.com')
.assert.text('#id', 'test')
.done();
}
};
RUNNING TEST - "Try to open an not existing URL freezes the test"
> OPEN http://not-existing-url.com
I wrote a simple test:
module.exports = {
'Click on bring fire': function (test) {
test
.open('http://bigpicture.ru/bigsochi/fire/136?sig=6f95fa441c50cca03d8a14b7b877676f')
.click('#fire_handler')
.screenshot('fakel.png')
.assert.text('#fire_handler').is('Готово !')
.done();
}
};
And when i have ran it with log level 5, i got:
Running tests
☁ [SYSTEM] dalek-internal-driver: Loading driver: "native"
Running Browser: PhantomJS
☁ [WEBDRIVER] webdriver: 404 POST /wd/hub/session
☁ [WEBDRIVER] webdriver: Error - Cannot find module 'cookiejar'
>> ERROR: SyntaxError: Unexpected token E
When i have installed cookiejar manually by npm install cookiejar i got:
Running tests
☁ [SYSTEM] dalek-internal-driver: Loading driver: "native"
Running Browser: PhantomJS
☁ [WEBDRIVER] webdriver: 404 POST /wd/hub/session
☁ [WEBDRIVER] webdriver: TypeError - 'undefined' is not a function (evaluating 'require('cookiejar').create()')
>> ERROR: SyntaxError: Unexpected token T
Also i tried to update phantomjs binary manually to version 1.9.7 and nothing changed.
Right now when you open a page you have to pass in the full url. Now I think is it is pretty common case that most of the tests within an application/library are going to reference 1 main domain so have to type that in for each test is quite repetitive. Now while it is possible to just have a javascript file that includes configurable variables and require that for each test file (which is what I currently do) so you could do something like this:
var variables = require('./config/variables');
//in a test
test.open(variables.baseUrl + '/some-page')
I think it would be a good idea to have this configurable in the Dalekfile (since I think this would be useful to a lot of people) so that you could simplify this even further to just:
//in a test
test.open('/some-page')
Dalek will read the location and if it starts with a '/' and there is a baseUrl in the configuration, it will automatically prepend it.
I should note that you would still be able to pass it absolute urls and they would continue to work as they do now.
The notVisible()
assertion requires the element to be found in the DOM. If it can't find an element, the assertion fails. The docs should note this and the cirumstances an element is deemed invisible (CSS properties display
and visible
, what about the element being off-viewport or having no dimensions width:0;height:0;overflow:none
etc pp.)
Should there be an assertion that unifies doesntExist() or notVisible()
?
I try to install DalekJS on my windows machine (Win7) following the "get started" tutorial.
NodeJs upgraded to 0.10.20
npm upgraded to 1.3.11
I first sucessfull install dalekjs-cli
After that when i run dalek -v i get theses errors: Cannot find module 'dalekjs', Cannot find module 'dalekjs-canary'
Seems logic for me because these two modules aren't here.
Switching to a web project folder i create the package json file, and install dalekjs with npm install dalekjs --save
Runing dalek -v i did'nt get what is expected :
DalekJS CLI Tools Version: 0.0.2
Brought to you with love by: Sebastian Golasch (@asciidisco) 2013
and not
DalekJS CLI Tools Version: 0.0.2
DalekJS local install : 0.0.7
Brought to you with love by: Sebastian Golasch (@asciidisco) 2013
It seems by checking dalek-cli code that it is around the local detection of dalekjs with node resolve.
Regards
Right now you have to specify each test file individually but if you have all your test files in the same folder, you should be able to do something like this:
{
"tests": [
"dalek/*.js"
]
}
This way you just write one line to include all the files and you don't have to worry about missing new ones since they will automatically be included.
There isn't any documentation for config
yet. We need a central page explaining how ENV, CLI and file configuration come together. In which order they're processed and for which circumstances you'd use either of them.
For documenting other methods (e.g. Actions/setHttpAuth) we could then link to this documentation and cut down on individual examples substantially.
We might want to simplify the API itself as well, go from test.config.get('USER')
to test.config.user
or something like that.
A suite could provide suite-scoped overwrites for config values in its options property. In the Q-Project, we might use this to run tests against local and remote environments without duplicating too much of the suite setup.
When chaining actions/assertions in a test, I have one of two approaches:
As this is a TestCase wide decision, we should have TestInstance.abortOnFailure(true)
to engage this mode. The Suite
might allow to configure this for all its tests. For this we could do with
{
options: {
abortOnFailure: true
},
// tests...
};
It would be pretty nice if I could define a base URL to which all requests (except otherwise noted) will be send to.
If I configured a base URL like http://github.com/dalekjs
and then use open('dalek/issues/new')
, the real request would be send to http://github.com/dalekjs/dalek/issues/new
.
If I'm inside a development environment I could send them all to http://localhost
, if I want to test a deployed application I could easily change it to http://github.com
.
When I query an element to test its text, I can't discern a failure caused by the element not being there and the element having the wrong text. Whenever I query an element and it can't be found - log an appropriate warning in order to make tests a bit more debuggable / approachable
.assert.text('.selector').is('text content')
// should log a warning when .selector can't be found
waitFor() does not properly work however execute() does. Turning on the logging revealed that the args parameter was not an array and when I looked at the code I noticed this line is missing in the waitFor() action but not in the execute() action (which is why execute was working):
var args = [this.contextVars].concat(Array.prototype.slice.call(arguments, 1) || []);
I have fixed this locally and everything seems to be working now. I will submit a pull request that fixes this later tonight.
The documentation for waitForElement()
- and any other single element action should note that a selector matching multiple elements will use the first element of that set - link to document.querySelector()
Here is the same hint which i wrote in Macros/Functions/Modules, maybe there are established javascript/nodejs-possibilities to include sub tests in your main tests. It makes sense if you have multiple test paths which differs to each other, but have similar parts, for example forms, which cannot be integrated in an separate calling test, because of preconditions (login, fill another form, ...) which must be granted before you can call and fill the form.
The greater idea as a more complete model is to create test templates at all, for organizing your complex tests.
Is there any way to include a bootstrap file or something similar to karma.conf.js
? If yes - sorry, I couldn't find it. If no - what's the best practice to configure base urls etc?
I'm not using dalek with Grunt.
per http://stackoverflow.com/q/20413951/1546710 and http://stackoverflow.com/a/21410355/1546710
A desired feature at the time was to automate file upload from the filesystem upload dialog. Sometimes a user can enter url instead, however, a full automated testing suite for the purposes should have required this feature. Thank you for consideration!
Dalek-Version: 0.0.8
MacOS Maverick
Test-File:
module.exports = {
'SSID Cookie test': function (test) {
test
.open('http://www.google.de/')
// Example content "A8QojqQJe5XrplYCu"
.assert.cookie('SSID').to.match("/[a-zA-Z0-9]/")
.done();
},
}
Call:
dalek test/cookie.js
Output:
Running tests
Running Browser: PhantomJS
OS: mac unknown 32bit
Browser Version: 1.9.2
RUNNING TEST - "SSID Cookie test"
▶ OPEN http://www.google.de/
After this nothing will happen.
Expected result is that the process will continue with tests.
Hi!
Trying out Dalekjs. But I am not able to run the first sample test. Dalek just hangs.
My test file:
module.exports = {
"Page title is correct": function (test) {
test
.open('http://google.com')
.assert().title().is('Google', 'Hooray!')
.done();
}
};
When running dalek the terminal just freezes:
dalek test/hello_test.js
Running tests
Running Browser: Phantomjs
OS: mac 10.8 (Mountain Lion) 32bit
Browser Version: 1.9.1
That's it.
dalek -v
DalekJS CLI Tools Version: 0.0.1
DalekJS local install: 0.0.1
OS
OS X 10.8.4 (12E55)
node -v
v0.10.15
If you attempt to require()
a module/file that doesn't exist DalekJS will be stuck on
Running tests
<> [SYSTEM] Loading driver: "native"
forever & never make any actual progress. I haven't dug into why yet because I'm still just trying to use it for basic testing stuff. Here's a tiny repro.
require("./fooga"); // "fooga.js" doesn't exist
module.exports = {
"test" : function(test) { ... }
};
Local DalekJS install info:
C:\Users\pcavit\Desktop\dalek>dalek -v
DalekJS CLI Tools Version: 0.0.1
DalekJS local install: 0.0.1
I'm trying to pass multiple keys Cmd Alt P
at the same time to Dalek to test page behavior:
test
.open('themes/ribbon/index.html')
.sendKeys('body', '\uE03D\uE00A\u0050') // Cmd Alt P
.assert.attr('body', 'class', 'full')
.done();
And it seems doesn't work as test is failing. I'm using W3C WebDriver spec for key codes reference, but I haven't found clear description on how to send multiple keys (both in Dalek docs and spec), especially with regular, not special ones like Alt and Cmd.
The same test with just a F5
works fine, of course:
test
.open('themes/ribbon/index.html')
.sendKeys('body', '\uE035') // F5
.assert.attr('body', 'class', 'full')
.done();
Dalek is a JavaScript library. "Native" Javascript formats are JSON and JS. The config currently supports YAML, JSON5 and CoffeeScript as well. This support is the only reason the packages js-yaml, json5 and coffee-script are required.
If anyone wants to use these formats (or the currently missing XML, plist, whatever) have them load the dependency themselves.
I'm not likely to use ALL of these formats in one dalek instance, so it's a waste to require them all. Get rid of them!
If you want to make it dead-simple to use CoffeeScript, maybe add a package "dalek-config-coffeescript" to have the package downloaded and registered (extenstion, read-function) with Conifg.
I'm not getting error messages / stack traces of problems my tests may have. Instead I'm presented with the utterly useless (and easy to miss) message "WARNING: done not called!".
I need to see what I did wrong here. Tests need to halt. This is a JavaScript error. I tried to invoke a function that doesn't exist. My test is flawed - stop and yell!
{
foo: function(test) {
test
// Note that this should be .assert.doesntExist()
.doesntExist('.selector')
// this isn't called
.done();
}
}
I tried it with
.waitForElement('a.vd-box')
.assert.attr('a.vd-box', 'href', 'http://www.youtube.com/watch?v=' + video)
.click('a.NOT_EXISTING_CLASS')
.waitForElementPresent('iframe.mfp-iframe')
.assert.attr('iframe.mfp-iframe', 'src', 'http://www.youtube.com/embed/'+video+'?autoplay=1&iv_load_policy=3')
.done();
}
I would expect an error raised for the missing element, instead there is a silent error and the following waitForElementPresent fails to get executed.
DalekJS CLI Tools Version: 0.0.4
DalekJS local install: 0.0.8
on PhantomJS 1.9.7 / Mac OSx 10.9.2
Would it be great to have the possibility to test portion of code after some manipulations ?
Like this :
dalek
.open( "http://localhost" )
.click( "#user-login > a" )
.type( "#email", "[email protected]" )
.type( "#password", "test" )
.submit( "#user-login > .box form" )
.assert.eval( window.app.connected, false, "user is not connected" )
.done()
I eventually can try to code and make a pull request, but I want to know if the feature is potentially interesting for the project.
Thanks in advance,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.