Giter Site home page Giter Site logo

robotframework-seriallibrary's People

Contributors

gerryqd avatar whosaysni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

robotframework-seriallibrary's Issues

Read Until discards read data on failed test

I am using Read Until extensively in my testing, however on failed tests I do not have any way of knowing what the serial output was. All I know is that it did not find what it was expecting. For some cases seeing what was sent during a failed test can greatly help debug.

Python not being my forte, I have been trying to implement something with the same functionality as Read Until but have it also return the data.
I have had no luck. Can you provide some insight as to how you would accomplish this?

Sending arrow keys on serial port

Hello,

I'm not able to send arrow keys on the serial port and get the result. This would be very helpful for testing behaviors like "fetch the last entry in the history file" (in my case the last command executed is returned from the device on the serial port after pressing the arrow-up key once).

Using a terminal (e.g. minicom) I can do this:

  • open minicom with proper settings
  • press the arrow-up key
  • observe the command line sent previously to the device

I try to simulate it with robotframework and seriallibrary with the following test case:

Library    SerialLibrary    encoding=ascii

MyTest
    ${arrow_up} =    Set Variable    Esc[1A
    Write Data    ${arrow_up}
    ${output} =         Read Until

and at the end ${output} will contain the characters Esc[1A instead of the last executed command. I guess my mistake is that I'm not escaping properly the special character sequence. If this is the case, could you please improve the documentation in order to explain how to do it? If this is not possible in the seriallibrary, would you consider covering this scenario?

How to read from a virtual USB device?

Could you share an example of connecting to a Linux device over a virtual USB device, e.g., /dev/ttyUSB0 and executing commands and reading output? I have been trying, but with not much success. Here is an example that does not work:

*** Settings ***
Library                             SerialLibrary    /dev/ttyUSB0    encoding=ascii

Test Setup                          Open serial port
Test Teardown                       Delete all ports

*** Test Cases ***

Bootloader messages should contain the desired values
    ${read} =                       SerialLibrary.Read until    terminator=login:
    Write data                      root\n
    ${read} =                       SerialLibrary.Read all data
    Log to console                  Console output: ${read}
    Should contain                  ${read}    root@ls1021atwr:/#

*** Keywords ***

Open Serial Port
    Set Port Parameter              baudrate    115200    port_locator=/dev/ttyUSB0
    Open port
    Port should be open

With a command such as picocom -b 115200 /dev/ttyUSB0, I get a login prompt, where I can enter the username root and then I get the prompt. Could you tell me how I could reproduce this behaviour with the SerialLibrary?

Thanks in advance!

Set RS485 Mode Attribute Error

When you use your 'Set Rs485 Mode' Keyword you receive an the following Error:
'Attribute Error: 'bool' object has no attribute 'rts_level_for_tx'
I think this is because you set 'Serial.rs485_mode' to a Boolean value rather than an instance of the 'rs485.RS485Settings' object as stated in the pySerial documentation.
If you remove the Boolean value and the argument 'status' from your function it works because the function assumes the default RS485 settings. However a better solution would be to give the user the option of changing the parameters of 'rs485.RS485Settings'.

testsuite not working with python 3.8

 $ robot test_library.robot 
==============================================================================
Test Library                                                                  
==============================================================================
Default port is None                                                  | PASS |
------------------------------------------------------------------------------
Default encoding is hexlify                                           | PASS |
------------------------------------------------------------------------------
Default parameters are set as same as a vanilla SerialBase instance   | PASS |
------------------------------------------------------------------------------
Get Encoding should return current encoding                           | PASS |
------------------------------------------------------------------------------
Set Encoding should change current encoding, returning previous value | PASS |
------------------------------------------------------------------------------
List Com Ports should return list of ports                            | PASS |
------------------------------------------------------------------------------
Com Port Should Exist Regexp should find some port                    | PASS |
------------------------------------------------------------------------------
Set Default Parameters changes internal default dictionary            | PASS |
------------------------------------------------------------------------------
Get Current Port Locator returns current port locator                 | PASS |
------------------------------------------------------------------------------
Current Port Should Be confirms current port locator                  | PASS |
------------------------------------------------------------------------------
Current Port Should Be Regexp confirms current port locator by reg... | PASS |
------------------------------------------------------------------------------
If no current port is assigned, Add Port will add one and make it ... | PASS |
------------------------------------------------------------------------------
Add Port fails if invalid or duplicaed port is tried                  | PASS |
------------------------------------------------------------------------------
Delete Port deletes specified port (or current port)                  | PASS |
------------------------------------------------------------------------------
Delete All Ports deletes all ports added so far                       | PASS |
------------------------------------------------------------------------------
Open Port should open closed port                                     | PASS |
------------------------------------------------------------------------------
Port Should Be Open/Closed should pass/fail depending on port status  | PASS |
------------------------------------------------------------------------------
Switch Port should switch port                                        | PASS |
------------------------------------------------------------------------------
Get/Set Port Parameter should get/set specified parameter             | PASS |
------------------------------------------------------------------------------
Read All Data should read all data arrived to the port                | PASS |
------------------------------------------------------------------------------
Read Data Should Be should fail if read bytes not equals to specif... | PASS |
------------------------------------------------------------------------------
[ WARN ] 01 23 45 67 89 AB CD EF                                              
Read All And Log should write log in specified loglevel.              | PASS |
------------------------------------------------------------------------------
Read Until should read until terminator or size                       | FAIL |
TypeError: read_until() got an unexpected keyword argument 'terminator'
------------------------------------------------------------------------------
Read Until should work with string terinators                         | FAIL |
Keyword 'SerialLibrary.Read Until' got unexpected named argument 'terminator_encoding'.
------------------------------------------------------------------------------
Port Should (Not) Have Unread Bytes passes/failes according to the... | PASS |
------------------------------------------------------------------------------
Read N Bytes should read specified number of bytes                    | PASS |
------------------------------------------------------------------------------
Flush port should flush i/o (this test just confirm no errors with... | PASS |
------------------------------------------------------------------------------
Reset Input Buffer clears input buffer.                               | PASS |
------------------------------------------------------------------------------
Reset Output Buffer clears output buffer.                             | PASS |
------------------------------------------------------------------------------
Send Break should send break (just comfirms no errors)                | PASS |
------------------------------------------------------------------------------
Set/get RTS should set/get RTS status                                 | PASS |
------------------------------------------------------------------------------
Get CTS Status should return CTS status                               | PASS |
------------------------------------------------------------------------------
Get DSR Status should return DSR status                               | PASS |
------------------------------------------------------------------------------
Get RI Status should return RI status                                 | PASS |
------------------------------------------------------------------------------
Get CD Status should return CD status                                 | PASS |
------------------------------------------------------------------------------
Set RS485 Mode without parameters should disable rs485 mode           | PASS |
------------------------------------------------------------------------------
Set RS485 Mode should accept rs485 mode parameters                    | PASS |
------------------------------------------------------------------------------
Write File Data should write content of specified file                | PASS |
------------------------------------------------------------------------------
Deleting one of multiple opened port should success                   | FAIL |
TypeError: 'odict_keys' object is not subscriptable
------------------------------------------------------------------------------
Hello serial test                                                     | PASS |
------------------------------------------------------------------------------
Hello serial test in unicode                                          | PASS |
------------------------------------------------------------------------------
Test Library                                                          | FAIL |
41 tests, 38 passed, 3 failed
==============================================================================

Connect to a System over Serial and run a Command

Hello Guys,
With Robot, I'd like to connect to a system (modem) over COM24 and execute command.
I created a robot Script (see below) using seriallibrary, the Robot ran with no errors but I didn't see those commands being executed in the remote system as I wish. would it be possible to write the ggood robot script please?

Serial Ports Settings must be: baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=1.0, xonxoff=False, rtscts=False, dsrdtr=False

Usually, I use Putty to connect to my system over Serial
once i'm connected into it, I write the command "AT+CGATT=0 ( or 1) and I hit "ENTER" to execute it

  • Settings ***
    Library SerialLibrary

*** Variables ***
${ComPort} COM24

*** Test Cases ***
ListComPorts
@{ports} = List Com Ports
Log ${ports[0].device}

AddPort
Add Port ${ComPort}

SetPortParameter
Set Port Parameter baudrate 115200

OpenPort
Open Port ${ComPort}

WriteData
Write Data AT+CGATT=0 encoding=ascii
Send Break
Send Break 0.5
Read All And Log loglevel=debug encoding=ascii
Write Data AT+CGATT=1 encoding=ascii
Send Break
Send Break 0.5
Read All And Log loglevel=debug encoding=ascii

ClosePort
Close Port ${ComPort}

*** Keywords *

##Thanks in Advance"

error to install on python3.8/windows x64

> C:\Users\admin\AppData\Local\Programs\Python\Python38\Scripts>pip install robotframework-seriallibrary==0.2.1
> Collecting robotframework-seriallibrary==0.2.1
>   Using cached robotframework-seriallibrary-0.2.1.tar.gz (8.1 kB)
>   Preparing metadata (setup.py) ... error
>   ERROR: Command errored out with exit status 1:
>    command: 'c:\users\admin\appdata\local\programs\python\python38\python.exe' -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\admin\\AppData\\Local\\Temp\\pip-install-x4njfoo7\\robotframework-seriallibrary_dfb9d411782242eab3e2d406420ceea0\\setup.py'"'"'; __file__='"'"'C:\\Users\\admin\\AppData\\Local\\Temp\\pip-install-x4njfoo7\\robotframework-seriallibrary_dfb9d411782242eab3e2d406420ceea0\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base 'C:\Users\admin\AppData\Local\Temp\pip-pip-egg-info-6_mll9me'
>        cwd: C:\Users\admin\AppData\Local\Temp\pip-install-x4njfoo7\robotframework-seriallibrary_dfb9d411782242eab3e2d406420ceea0\
>   Complete output (15 lines):
>   C:\Users\admin\AppData\Local\Temp\pip-install-x4njfoo7\robotframework-seriallibrary_dfb9d411782242eab3e2d406420ceea0\setup.py:3: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
>     from imp import load_source
>   Traceback (most recent call last):
>     File "<string>", line 1, in <module>
>     File "C:\Users\admin\AppData\Local\Temp\pip-install-x4njfoo7\robotframework-seriallibrary_dfb9d411782242eab3e2d406420ceea0\setup.py", line 21, in <module>
>       VERSION = load_source(
>     File "c:\users\admin\appdata\local\programs\python\python38\lib\imp.py", line 171, in load_source
>       module = _load(spec)
>     File "<frozen importlib._bootstrap>", line 702, in _load
>     File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
>     File "<frozen importlib._bootstrap_external>", line 844, in exec_module
>     File "<frozen importlib._bootstrap_external>", line 980, in get_code
>     File "c:\users\admin\appdata\local\programs\python\python38\lib\imp.py", line 152, in get_data
>       self.file = file = open(self.path, 'rb')
>   FileNotFoundError: [Errno 2] No such file or directory: 'version'
>   ----------------------------------------
> WARNING: Discarding https://files.pythonhosted.org/packages/ea/04/a07a8b0008eb8300c33644058c128093edad019f36bb63f230857fd17918/robotframework-seriallibrary-0.2.1.tar.gz#sha256=1b478b713e84ab1947e47570ce855f4c997ba3302760f34a2a16c5bf58c0be8c (from https://pypi.org/simple/robotframework-seriallibrary/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
> ERROR: Could not find a version that satisfies the requirement robotframework-seriallibrary==0.2.1 (from versions: 0.1.1, 0.2.0, 0.2.1, 0.2.2, 0.2.4, 0.3.1)
> ERROR: No matching distribution found for robotframework-seriallibrary==0.2.1

packaging issues

Thanks for this!

It looks like the poetry dependencies are mis-specified, leaving the package on pypi with the generated setup.py saying:

install_requires = \
['install_requires', 'install_requires']

PR incoming!

pip3 install show wrong version

$ sudo pip3 uninstall robotframework-seriallibrary
WARNING: Skipping robotframework-seriallibrary as it is not installed.
$ sudo pip3 install git+https://github.com/whosaysni/robotframework-seriallibrary@develop
Collecting git+https://github.com/whosaysni/robotframework-seriallibrary@develop
  Cloning https://github.com/whosaysni/robotframework-seriallibrary (to revision develop) to /tmp/pip-req-build-a0m0vbmn
  Running command git clone -q https://github.com/whosaysni/robotframework-seriallibrary /tmp/pip-req-build-a0m0vbmn
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Requirement already satisfied: install_requires in /usr/local/lib/python3.8/dist-packages (from robotframework-seriallibrary==0.4.2) (0.3.0)
Building wheels for collected packages: robotframework-seriallibrary
  Building wheel for robotframework-seriallibrary (PEP 517) ... done
  Created wheel for robotframework-seriallibrary: filename=robotframework_seriallibrary-0.4.2-py2.py3-none-any.whl size=9943 sha256=dc0e896681ad5c7851c4e2b32be814318873c0193cbc22706998c778e75e6a3a
  Stored in directory: /tmp/pip-ephem-wheel-cache-ggpe9cck/wheels/e4/b8/47/f5504952bbcdf6e5e1085e21e2be19f3c5d038cf511ed74b00
Successfully built robotframework-seriallibrary
Installing collected packages: robotframework-seriallibrary
Successfully installed robotframework-seriallibrary-0.4.2
$ python3 -m pip list | grep robotframework-seriallibrary
robotframework-seriallibrary 0.3.1               

Python 3 support of multiple ports

Hi guys,

First of all, thanks for this module, very helpful!

I got an error while porting my *.robot file to be executed in Python 3.
Basically, I open a serial port, then I open a second one, switch to it, make some data exchanges and finally delete it:

TC1
    [Setup]    Open Primary Serial Port
    Write Data    Hello on Primary port\n
    [Setup]    Open Auxiliary Serial Port
    Switch Port    ${COMPORT2}
    Write Data    Hello on Secondary port\n
    Delete Port    ${COMPORT2}
    [Teardown]    Delete All Ports


Open Primary Serial Port
    Add Port    ${COMPORT}    baudrate=115200    bytesize=8    parity=N    stopbits=1    timeout=1
Open Auxiliary Serial Port
    Add Port    ${COMPORT2}    baudrate=115200    bytesize=8    parity=N    stopbits=1    timeout=1

It seems that Delete Port ${COMPORT2} is raising the error "TypeError: 'odict_keys' object is not subscriptable". I tried running the same script with Python 2, everything works well.
It seems that dictionary is not used similarly across Python 2 and Python 3.

Error when Read Until is invoked with a string terminator

If in my robot-framework test case I write:

Test Bla
    Read Until  terminator=foo

then "foo" is passed as bytes, and thus I get the following error trace:

20190327 10:39:07.817 - FAIL - AttributeError: 'bytes' object has no attribute 'encode'
20190327 10:39:07.817 - DEBUG - Traceback (most recent call last):
  File "/home/XXX/.virtualenvs/atlc/lib/python3.6/site-packages/SerialLibrary/__init__.py", line 529, in read_until
    terminator = self._encode(terminator)
  File "/home/XXX/.virtualenvs/atlc/lib/python3.6/site-packages/SerialLibrary/__init__.py", line 177, in _encode
    return ustring.encode(encoding or self._encoding, encoding_mode)

At the moment the code in SerialLibrary.read_until is:

        if terminator != LF:
            terminator = self._encode(terminator)

First of all it seems incorrect that the invocation of self._encode does not forward the parameter encoding received by the read_until method.

Second, if the terminator is an object of type bytes (as passed by robotframework), it makes no sense to encode it. Thus, I would suggest to amend the code as follows (if you don't seen any trouble):

    if terminator != LF and not isinstance(terminator, bytes):
        terminator = self._encode(terminator, encoding)

Does it make sense to you?

not working with with RobotFramework 5.0

When I try to use the library with a statement like:

Library SerialPort COM3

I get an error message showing that this line:
from robot.utils.unic import unic"

of the init.py file fails.

AttributeError: 'bytes' object has no attribute 'encode'

Hi,

I'm trying to use a simple example to connect using serial config ( python --version
Python 3.8.10 )

*** Settings ***

Documentation   Test serial output

Library         SerialLibrary         encoding=ascii

*** Variables ***

${ASK_LOGIN}       MyBoard login:
${PROMPT}          root@MyBoard:~#

*** Test Cases ***
Log In And Run A Echo Command
    [Documentation]    Test

    [Setup]     Open Serial Port
    [Teardown]  Delete All Ports

    ${read} =    Read Until  terminator=${ASK_LOGIN}
    Should Contain     ${read}    ${ASK_LOGIN}
    Log   ${read}
    Write Data   root\r

    ${read} =    Read Until  terminator=Password:
    Should Contain     ${read}    Password:
    Log   ${read}

    Sleep  1

    Write Data   passwd123\r
    ${read} =    Read Until  terminator=${PROMPT}
    Should Contain     ${read}    ${PROMPT}
    Log          ${read}


*** Keywords ***

Open Serial Port
    Add Port   /dev/ttyUSB0
    ...        baudrate=115200
    ...        bytesize=8
    ...        parity=N
    ...        stopbits=1
    ...        timeout=999     # Dealing with the serial port at most for 999 seconds 

I get the following error :

==============================================================================
Serial :: Test serial output                                                  
==============================================================================
Log In And Run A Echo Command :: Test                                 | FAIL |
AttributeError: 'bytes' object has no attribute 'encode'
------------------------------------------------------------------------------
Serial :: Test serial output                                          | FAIL |
1 test, 0 passed, 1 failed
==============================================================================
Output:  /home/zaki/Projects/Playground/robot/output.xml
Log:     /home/zaki/Projects/Playground/robot/log.html
Report:  /home/zaki/Projects/Playground/robot/report.html

Install error (Python >= 3.7)

D:\>pip install robotframework-seriallibrary
Collecting robotframework-seriallibrary
  Using cached https://files.pythonhosted.org/packages/ce/e1/1e337dc84a20b9d92d7b243d16bb9f6fc0084967eca7454228bb546efec7/robotframework-seriallibrary-0.3.1.tar
.gz
    ERROR: Command errored out with exit status 1:
     command: 'c:\users\tysonite\appdata\local\programs\python\python37\python.exe' -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\tysonite
\\AppData\\Local\\Temp\\pip-install-vou9a4v7\\robotframework-seriallibrary\\setup.py'"'"'; __file__='"'"'C:\\Users\\tysonite\\AppData\\Local\\Temp\\pip-install-
vou9a4v7\\robotframework-seriallibrary\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.
close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base pip-egg-info
         cwd: C:\Users\tysonite\AppData\Local\Temp\pip-install-vou9a4v7\robotframework-seriallibrary\
    Complete output (13 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\tysonite\AppData\Local\Temp\pip-install-vou9a4v7\robotframework-seriallibrary\setup.py", line 23, in <module>
        open(join(CURDIR, 'src', 'SerialLibrary', 'version.py'))).VERSION
      File "c:\users\tysonite\appdata\local\programs\python\python37\lib\imp.py", line 171, in load_source
        module = _load(spec)
      File "<frozen importlib._bootstrap>", line 696, in _load
      File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 724, in exec_module
      File "<frozen importlib._bootstrap_external>", line 859, in get_code
      File "c:\users\tysonite\appdata\local\programs\python\python37\lib\imp.py", line 152, in get_data
        self.file = file = open(self.path, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: 'version'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Unable to open serial port from SSH in Robot Framework

*** Settings ***
Documentation   Automation Test for BVT
Library         SSHLibrary
Library         SerialLibrary       encoding=ascii

Test Setup     Open Connection and Log In
Test Teardown  Teardown


*** Test Cases ***

Test1
    Execute Command And Verify Output
    Open Serial Port


*** Keywords ***

Open Connection and Log In
    Open Connection  ${HOST}
    Login            ${SSH_USERNAME}  ${SSH_PASSWORD}

Teardown
    Close All Connections

Execute Command And Verify Output
    [Documentation]    Execute Command can be used to ran commands on the remote machine.
    ...                The keyword returns the standard output by default.
    ${output} =        Execute Command  echo Hello SSHLibrary!
    Should Be Equal    ${output}        Hello SSHLibrary!
    Execute Command    sudo killall minicom

Open Serial Port
    Add Port   /dev/ttyUSB0
    ...        baudrate=115200
    ...        bytesize=8
    ...        parity=N
    ...        stopbits=1
    ...        timeout=999     # Dealing with the serial port at most for 999 seconds

I want to be able to SSH into a device and also open a serial port from that box. I usually ssh@box and type in "sudo killall minicom" to kill all existing processes and "sudo -D minocom /dev/ttyUSB0" to connect to the device in which I am promoted by the password of the ssh@box then it allows me to serial into the board. The board then has a randomized user prompt, a password prompt, then after I enter those, I get the prompt.

Convert To Bytes does not escape values below 0x20

Hello, thanks for the work, I just started using it.

I refer to the
http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Convert%20To%20Bytes
Example shows the problem:
${bytes} = | Convert To Bytes | ff 00 07 | hex | # \xff\x00\x07

I expanded a bit to see what happens:

I expanded a bit to see what happens:
    ${bytes} = 	Convert To Bytes 	ff 00 07 	hex
    Log  ${bytes}   console=yes
    ${count} =    Get Length  ${bytes}
    Log  ${count}   console=yes
    ${text} = 	Convert To String 	${bytes}
    Log  ${text}   console=yes
    ${count} =    Get Length  ${text}
    Log   ${count}  console=yes

And I get

\xff
3
\xff
6

on terminal.

It seems to me as if it converts correct but doesn't escape 00 or 07 as in the example so they are not printed to the console and when making it back to text I see the same but with a length of 6 (4 for the escaped FF and 2 for the non printable ones). I am not sure if this is intended behavior as it is not technically false as they are ASCII chars but the example makes me think it's not intended.

If it's intended I suggest changing the example and maybe note it in the description.
Thanks for the work done.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.